简介
了解一下Aop中的目标对象和代理对象
测试代码(切面类和测试类在之前的aop基本使用中)
1 | public class Application { |
首先,将@EnableAspectJAutoProxy注解注释掉,调试一下。
然后,加上@EnableAspectJAutoProxy注解,调试一下。
那么上面的就是目标对象,下面的就是代理对象。那么接下来就在调试中去探索一下这个代理对象是如何产生。
源码调试
1 | AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.yb"); |
这行代码,了解spring的应该都是知道是用来初始化ioc容器,里面有个beanFactory,其中有个叫SingletonObjects,也就是所谓的单例池,里面就是保存所有的单例bean对象。其本质就是一个map,当我们调用getBean()时,就是从这个map中去查找,那么既然有get,那么肯定在实例化bean的时候有个,put的方法将这个bean放到这个map中。那么就查找一个是否存在一个SingletonObjects.put()这个方法。(ctrl+shift+f)全局查找,结果如下:
,根据方法名和参数,可以判断是第一个。
1 | protected void addSingleton(String beanName, Object singletonObject) { |
此时,我们在this.singletonObjects.put(beanName, singletonObject);出打个断点,并且加上断点条件————“springAopTest”.equals(beanName)(否则其他不相干的bean也会调用此方法),重新开始调试。
从上面的可以发现,此时的springAopTest确实已经是代理对象了,那么可以根据方法调用栈一步一步往前找。
getSingleton(其他本次调试无关的我都删了昂)
1 | public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { |
当执行完Object singletonObject = this.singletonObjects.get(beanName);时,可发现此时singletonObject是null,说明此时的singletonObjects中没有代理对象的(此时肯定没有啊,因为都没有调用put方法,哈哈哈哈),继续,当执行完singletonObject = singletonFactory.getObject();后,发现,此时代理对象出现了。那么继续看看这个singletonFactory.getObject()方法。
doGetBean
1 | protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, |
这里的getSinleton(beanName,()->{}),里面是个Lambda表达式代替的匿名类
1 | new ObjectFactory(){ |
看这名字creatbean,感觉应该是在这里没错了。调试一下看看
createBean
1 | protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) |
看下 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 上的注释:// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.给BeanPostProcessors(后置处理器)一个机会来返回一个代理对象代替目标对象。感觉好像是在这里生成代理对象的,但是执行之后发现bean居然是null,怎么肥四,就先继续往下走叭,当走到 Object beanInstance = doCreateBean(beanName, mbdToUse, args);时,发现代理对象出现了。
doGetBean (和之前的那个不一样)
1 | protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) |
instanceWrapper = createBeanInstance(beanName, mbd, args);这里创建了目标对象实例,instanceWrapper.getWrappedInstance()获取目标对象,一直到 exposedObject = initializeBean(beanName, exposedObject, mbd);这里才出现了代理对象。
initializeBean
1 | protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { |
执行了applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)后出现了代理对象
applyBeanPostProcessorsAfterInitialization
1 | public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) |
这个方法里主要是遍历后置处理器。并且执行其中的postProcessAfterInitialization方法,其中有很多的后置处理器,到底执行的是哪一个呢?(查了一下是AnnotationAwareAspectJAutoProxyCreator这个后置处理器)
它是从@EnableAspectJAutoProxy中@Import(AspectJAutoProxyRegistrar.class),其中有个registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);的方法
这里可以发现AnnotationAwareAspectJAutoProxyCreator确实是一个后置处理器。发现这个类中并没有postProcessAfterInitialization方法,然后在其父类(AbstractAutoProxyCreator)中找到了
1 | public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { |
进入此方法中,发现其中有个createProxy方法,代理对象就是在这里创建的
1 | // Create proxy if we have advice. |