# 作用
首先編寫兩個類作為測試
package com.fh.cglib; public class AopService { public void query(){ System.out.println("query"); } }
package com.fh.cglib; public class AopService1 { public AopService1(){ System.out.println("init aopService1..."); } }
然后在寫個測試用的配置類
package com.fh.cglib; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; @Component @Configuration public class AopConfig { @Bean public AopService getAopService(){ getAopService1(); return new AopService(); } @Bean public AopService1 getAopService1(){ return new AopService1(); } }
然后將配置類上的@Configuration去掉和添加分別啟動容器,你就會發現AopServoce1的對象初始化調用了兩次,對,這就是這個注解的作用
# 在Spring中的處理
AbstractApplicationContext#refresh
AbstractApplicationContext#invokeBeanFactoryPostProcessors
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
ConfigurationClassPostProcessor#processConfigBeanDefinitions
ConfigurationClassUtils#checkConfigurationClassCandidate
根據這個包結構,我們查看到類對注解的處理操作,可以發現是向beanDef中添加了一個屬性值
AbstractApplicationContext#refresh
AbstractApplicationContext#invokeBeanFactoryPostProcessors
AbstractApplicationContext#invokeBeanFactoryPostProcessors
ConfigurationClassPostProcessor#postProcessBeanFactory
ConfigurationClassPostProcessor#enhanceConfigurationClasses
然后我們根據這個包結構找到了對上面設置的屬性做的處理,發現如果是屬性設置成full的話,會通過cglib設置一個代理類對象
根據代碼中代理對象的設置,發現cglib動態代理添加了一個
EnhancedConfiguration接口,這個接口的父接口為我們提供了BeanFactory屬性,還添加了一個方法攔截數組,在方法攔截中做了一些處理,沒有直接調用具體的方法,而是通過判斷當前方法和正在執行的方法是否為同一個方法,是的話就執行被代理對象的方法。
不是的話,直接從BeanFactory中獲取,然后返回即可(具體處理沒有這么簡單)
方法的判斷
對象的獲取
后續有啥問題再做修改和補充