AOP目的:增强一个类-》方法
编写测试程序,获取bean
小概念:
- AOP:目标
- SpringAop、AspectJ:手段(两者是竞争对手)
一、aop应用
1、Enabling @AspectJ Support使项目支持aspectj风格
2、xml/@EnableAspectAutoProxy
3、编写一个切面
@Component
@Aspect //切面就是切点、连接点和通知所在的类
public class AspectDemo{
//切点(连接点的集合),连接点的最小单位是方法
@Pointcut("execution(* com.sc.dao..*.*(..))")
private void transfer(){
}
//一个通知:切入时机+切入内容
@Before("transfer")
public void advice(){
sout("------");
}
}
二、原理
查看获取的bean,发现变成了UserDao和几个属性值(被增强了)
假设:把包装后的UserDao放在spring容器中,将原生对象丢掉
问题:是在启动spring时增强对象还是使用的时候增强?
应该是在项目一启动的时候就增强
证明:
查看getBean方法:
- target object目标对象:UserDao
- AOP Proxy代理对象:增强的UserDao
resolveNamedBean已经把代理对象返回来了,所以需要看
其中getBean返回了代理对象:
查看其中的doGetBean方法:
如果这时proxy的object:
- 直接获取一个代理对象——项目启动产生
- 首先产生一个目标对象,然后对目标对象进行代理,返回代理对象——bean.getBean产生的(X)
发现初始化和getBean都会调用doGetBean方法:——》先进入getbean方法再加断点进入doGetBean
从单例池中(Map类型)获取:默认bean是单例
proxy对象是在init Spring
三、增强的操作都做了什么?
问题:从AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class)
进入到getSingleton方法获取的对象等不等于空?
等于空——
看什么时候往map里放东西:
doCreateBean:
- 创建目标对象
- 变成代理对象
可以看到目标对象被包裹类获取
最终是在这里完成aop处理
方法内部的applyBeanPostProcessorsAfterInitialization
BeanPostProcessor接口:
bean的生命周期中会在某处(切入点)循环调用BeanPostProcessor接口的实例对象列表,返回old/new/null三种对象(底层:jdk动态代理或者cglib)