- @Controller:修饰 web 层类
- @Service:修饰 service 层类
- @Repository:修饰 dao 层类
- 普通属性使用 @Value 来设置属性的值
- 对象属性使用 @Autowired ,这个注解是按照类型来进行属性注入的 。如果希望按照 bean 的名称或id进行属性注入,需要用 @Autowired 和 @Qualifier 一起使用
- 实际开发中,使用 @Resource(name=" ") 来进行按照对象的名称完成属性注入
- @PostConstruct 相当于 init-method,用于初始化函数的注解
- @PreDestroy 相当于 destroy-method,用于销毁函数的注解
- @Scope 作用范围的注解,常用的是默认单例,还有多例 @Scope("prototype")
- 适用场景:XML 适用于任何场景;注解只适合自己写的类,不是自己提供的类无法添加注解 。
- 可以使用 XML 管理 bean,使用注解来进行属性注入
AOP 能够对程序进行增强,在不修改源码的情况下,可以进行权限校验,日志记录,性能监控,事务控制等 。
也就是说功能分为两大类,一类是核心业务功能,一类是辅助增强功能 。两类功能彼此独立进行开发 。比如登录功能是核心业务功能,日志功能是辅助增强功能,如果有需要,将日志和登录编制在一起 。辅助功能就称为切面,这种能选择性的、低耦合的把切面和核心业务功能结合的编程思想称为切面编程 。
底层实现
JDK 动态代理只能对实现了接口的类产生代理 。Cglib 动态代理可以对没有实现接口的类产生代理对象,生成的是子类对象 。
使用 JDK 动态代理:
public interface UserDao {
public void insert();
public void delete();
public void update();
public void query();
}
实现类:
public class UserDaoImpl implements UserDao { @Override public void insert() { System.out.println("insert"); } @Override public void delete() { System.out.println("delete"); } @Override public void update() { System.out.println("update"); } @Override public void query() { System.out.println("query"); } }
JDK 代理:
public class JDKProxy implements InvocationHandler{
private UserDao userDao;
public JDKProxy(UserDao userDao){
this.userDao=userDao;
}
public UserDao createProxy(){
UserDao userDaoProxy=(UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
userDao.getClass().getInterfaces(), this);
return userDaoProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("update".equals(method.getName())){
System.out.println("权限校验");
return method.invoke(userDao, args);
}
return method.invoke(userDao, args);
}
}
通过动态代理增强了 update 函数 。测试类:
public class Demo1 {
@Test
public void demo1(){
UserDao userDao=new UserDaoImpl();
UserDao proxy=new JDKProxy(userDao).createProxy();
proxy.insert();
proxy.delete();
proxy.update();
proxy.query();
}
}
运行结果为:
insert
delete
权限校验
update
query
CglibCglib 是第三方开源代码生成类库,可以动态添加类的属性和方法 。
与上边JDK代理不同,Cglib的使用方式如下:
public class CglibProxy implements MethodInterceptor{
//传入增强的对象
private UserDao customerDao;
public CglibProxy(UserDao userDao){
this.userDao=userDao;
}
public UserDao createProxy(){
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(userDao.getClass());
enhancer.setCallback(this);
UserDao proxy=(UserDao)enhancer.create();
return proxy;
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if("save".equals(method.getName())){
System.out.println("enhance function");
return methodProxy.invokeSuper(proxy, args);
}
return methodProxy.invokeSuper(proxy, args);
}
}
如果实现了接口的类,底层采用JDK代理 。如果不是实现了接口的类,底层采用 Cglib代理 。
IOC与传统方式的比较
- 获取对象方式:传统通过 new 关键字主动创建一个对象 。IOC 方式中,将对象的生命周期交给 Spring 管理,直接从 Spring 获取对象 。也就是控制反转————将控制权从自己手中交到了 Spring 手中 。
推荐阅读
- 抖音客服的工作靠谱么 抖音售后客服是干嘛的
- 淘宝店铺的规则主要有哪一些 开淘宝店的规则是什么
- 淘宝不按时发货的惩罚 淘宝店铺未按照约定时间发货有赔偿吗
- 推荐几个开发必备的JSON工具
- 福鼎大白茶,福鼎大白茶的优势
- 福鼎大毫茶,福鼎大白与福鼎大毫茶树的生长条件介绍
- 提高搜索引擎对网站信用度的方法
- 升级win10系统必须要做的5件事,装机、重装系统必知
- 与程序员相关的CPU缓存知识
- 福建绿茶,福建的绿茶种类