@Configuration 原理
一、执行这个注解的位置ConfigurationClassPostProcessor
refresh();
invokeBeanFactoryPostProcessors(beanFactory); 在方法中执行beanFactoryPostProcess后置处理器
invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);执行beanFactoryPostProcess后置处理器
执行ConfigurationClassPostProcessor类的postProcessBeanFactory方法
二、postProcessBeanFactory
enhanceConfigurationClasses(beanFactory);
1)循环遍历所有的BeanDefinition进行如下操作
ConfigurationClassUtils.isFullConfigurationClass(beanDef)判断是否是全注解(这个类是否有@Configuration注解)
如果有这个注解将beanDef放到Map中 configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
2)创建new ConfigurationClassEnhancer类,类中创建了三个拦截对象,用于对创建的增强对象进行拦截
new BeanMethodInterceptor(),
new BeanFactoryAwareMethodInterceptor(),
NoOp.INSTANCE
这三个类都实现了MethodInterceptor接口
3)循环遍历所有的configBeanDefs(其中存放的所有的加了@Configuration的类)进行如下操作
enhancer.enhance(configClass, this.beanClassLoader); 通过cglib创建代理对象
三、如何创建代理对象
1)if (EnhancedConfiguration.class.isAssignableFrom(configClass)) return configClass;
如果是EnhancedConfiguration.class类型则直接返回(在创建完的代理对象后,会给代理对象设置成接口为EnhancedConfiguration类型)
换句话来说就是如果是这个类型则代表这个对象已经增强过了
2)没有被代理则 createClass(newEnhancer(configClass, classLoader));
其中的newEnhancer(configClass, classLoader)
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(superclass); //设置增强类继承superclass
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class}); //设置代理对象的实现接口,便于判断是否被增强
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);//设置名字
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));//在代理类中添加一个属性
1.在BeanFactoryAwareGeneratorStrategy的transform方法中
declare_field(Constants.ACC_PUBLIC, BEAN_FACTORY_FIELD, Type.getType(BeanFactory.class), null);
添加了一个公共的 名字为 BEAN_FACTORY_FIELD常量 的 BeanFactory.class
(相当于在@Configuration所在的类中添加了一个BeanFactory类型的成员变量,用于调用getBean获得对象)
enhancer.setCallbackFilter(CALLBACK_FILTER); (传入ConfigurationClassEnhancer类中的三个拦截器)
new BeanMethodInterceptor(),
new BeanFactoryAwareMethodInterceptor(),
NoOp.INSTANCE
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
四、是如何增强的主要是这三个过滤器(这里比较难)
拦截方法 intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,MethodProxy cglibMethodProxy)
拦截的beanMethod是@Configuration 所在类中的方法
1)new BeanMethodInterceptor(),
isCurrentlyInvokedFactoryMethod(beanMethod) //判断调用方法和创建方法是否是同一个
如果是创建对象
如果不是从ioc容器中获取,如果没有则创建
2)new BeanFactoryAwareMethodInterceptor(),
3)NoOp.INSTANCE
五、如果是static则会失效原因
@Configuration
public class PersionConfig {
@Bean
public static Persion persionBean(){
return new com.lizhiyu.studyaspects.Persion();
}
@Bean
public Acpects acpectsBean(){
persionBean();
return new Acpects();
}
在ConfigurationClassPostProcessor的 processConfigBeanDefinitions 方法中的
this.reader.loadBeanDefinitions(configClasses);
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
loadBeanDefinitionsForBeanMethod(beanMethod);
if (metadata.isStatic()) { //如果是静态的 应该是设置成了一个factorybean
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
beanDef.setFactoryMethodName(methodName);
}
else {
beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(methodName);
}