zoukankan      html  css  js  c++  java
  • 面向切面编程AOP[四](java AnnotationAwareAspectJAutoProxyCreator与ioc的联系)

    前言

    拿出上一篇的内容:

    AnnotationAwareAspectJAutoProxyCreator
    extends AspectJAwareAdvisorAutoProxyCreator
    AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator
    AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator
    AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
    

    正文

    在这里和ioc相关的有两个东西一个是:

    SmartInstantiationAwareBeanPostProcessor,BeanFactoryAware
    
    SmartInstantiationAwareBeanPostProcessor 表示bean 在注入容器前后做些什么。
    

    那么联系AOP和 IOC 的联系,那么就来分析继承IOC的东西吧。

    在BeanFactoryAware 中:

    public interface BeanFactoryAware extends Aware {
        void setBeanFactory(BeanFactory var1) throws BeansException;
    }
    

    那么AbstractAutoProxyCreator 继承它,肯定会实现setBeanFactory。

    找到这个方法:

    public void setBeanFactory(BeanFactory beanFactory) {
            this.beanFactory = beanFactory;
        }
    

    继续往上看:
    AbstractAdvisorAutoProxyCreator 看看是否有覆盖setBeanFactory的东西。

    public void setBeanFactory(BeanFactory beanFactory) {
    	super.setBeanFactory(beanFactory);
    	if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
    		throw new IllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
    	} else {
    		this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
    	}
    }
    

    果然上面有覆盖的东西。

    异常的先不看,因为异常是细节,然后如果不出问题的话,那么会执行:

    this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);

    看下这个:initBeanFactory

    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            this.advisorRetrievalHelper = new AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
        }
    

    那么继续往上AspectJAwareAdvisorAutoProxyCreator ,这下看的就是是否覆盖了setBeanFactory 或者initBeanFactory:

    查到到其并没有覆盖。

    继续到最上层:AnnotationAwareAspectJAutoProxyCreator,发现覆盖了initBeanFactory:

    protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    	super.initBeanFactory(beanFactory);
    	if (this.aspectJAdvisorFactory == null) {
    		this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
    	}
    
    	this.aspectJAdvisorsBuilder = new AnnotationAwareAspectJAutoProxyCreator.BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
    }
    

    那么好的,看断点。
    在AbstractAdvisorAutoProxyCreator:

    在这里不用猜,一般都是set进入的。

    那么看下在setFactory 之前做了什么。

    首先加载config。

    AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigofAOP.class);

    然后注册组件:

    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    	this();
    	this.register(componentClasses);
    	this.refresh();
    }
    

    this.refresh();
    刷新容器。

    看下刷新容器做了什么。

    记得在我上一个里面,我写道,AOP之所以与IOC 紧密挂钩是因为,IOC 注册容器的时候,AOP会监听到。

    那么来看下refresh做了什么。

        public void refresh() throws BeansException, IllegalStateException {
            synchronized(this.startupShutdownMonitor) {
                this.prepareRefresh();
                ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
                this.prepareBeanFactory(beanFactory);
    
                try {
                    this.postProcessBeanFactory(beanFactory);
                    this.invokeBeanFactoryPostProcessors(beanFactory);
                    this.registerBeanPostProcessors(beanFactory);
    

    this.registerBeanPostProcessors(beanFactory); 这个就是注册了容器创建的后置处理器,也就是说在容器创建之前监听,说白了就是拦截器。

    看下里面是怎么注册的。

    进入registerBeanPostProcessors进行处理:

    for(int var10 = 0; var10 < var9; ++var10) {
                ppName = var8[var10];
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
                    priorityOrderedPostProcessors.add(pp);
                    if (pp instanceof MergedBeanDefinitionPostProcessor) {
                        internalPostProcessors.add(pp);
                    }
                } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessorNames.add(ppName);
                } else {
                    nonOrderedPostProcessorNames.add(ppName);
                }
            }
    

    把以前注册过的容器做一个处理:

    如果实现接口 PriorityOrdered.class优先注册。

    然后是Ordered.class 注册容器。

    然后是注册既没有实现PriorityOrdered.class 和 Ordered.class的注册容器。

    前面把他们分完类之后,那么就开始去注册容器了,看下如何注册容器的。

    while(var14.hasNext()) {
                String ppName = (String)var14.next();
                BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
                orderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            }
    

    注册容器就是去getBean。

    然后去执行:

     if (mbd.isSingleton()) {
                        sharedInstance = this.getSingleton(beanName, () -> {
                            try {
                                return this.createBean(beanName, mbd, args);
                            } catch (BeansException var5) {
                                this.destroySingleton(beanName);
                                throw var5;
                            }
                        });
                        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                    }
    

    通过createBean 去创建然后注册到容器中。

    createBean 里面有一个:

     beanInstance = this.doCreateBean(beanName, mbdToUse, args);
    

    也就是有一个doCreateBean。

    创建完bean 后然后执行:

    this.populateBean(beanName, mbd, instanceWrapper);
    

    也就是给属性赋值。
    然后初始化initializeBean:

    exposedObject = this.initializeBean(beanName, exposedObject, mbd);
    

    看下如何初始化Bean。
    1.this.invokeAwareMethods(beanName, bean);
    看下invokeAwareMethods 有什么。

    private void invokeAwareMethods(String beanName, Object bean) {
    	if (bean instanceof Aware) {
    		if (bean instanceof BeanNameAware) {
    			((BeanNameAware)bean).setBeanName(beanName);
    		}
    
    		if (bean instanceof BeanClassLoaderAware) {
    			ClassLoader bcl = this.getBeanClassLoader();
    			if (bcl != null) {
    				((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
    			}
    		}
    
    		if (bean instanceof BeanFactoryAware) {
    			((BeanFactoryAware)bean).setBeanFactory(this);
    		}
    	}
    
    }
    

    看一下这个注册的bean 是否有Aware注解,setBeanFactory。然后就来到了,我们断点的地方。

    当invokeAwareMethods执行完毕后:

    wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    

    给方法增加监听器,然后就ok了。

  • 相关阅读:
    Linux Shell for循环写法总结 皇星客栈
    关于adr指令的理解 皇星客栈
    lds linux下的通用链接脚本 皇星客栈
    2430实验点对点通信实验 皇星客栈
    #pragma vector 皇星客栈
    linux下firefox安装Adobe Flash Player插件 皇星客栈
    一个shell脚本引发的对于分号(;)和$#的使用说明(转载) 皇星客栈
    代码打开wince自带的wif配置窗口i
    C#数组的合并拆分
    Coding4Fun
  • 原文地址:https://www.cnblogs.com/aoximin/p/12969752.html
Copyright © 2011-2022 走看看