- full和lite的区别如下
- full模式区别的实现一ConfigurationClassPostProcessor.postProcessBeanFactory
- 增强的目的以及实现
- 目的
- 实现
- BeanFactoryAwareMethodInterceptor作用
- BeanMethodInterceptor完成full模式实现
- 总结
- full输出:
com.renxl.demo.Hi2@12ae75f1
com.renxl.demo.Hi2@12ae75f1
@Configuration
public class ConfigClass {
@Bean
public Hi1 hi1() {
System.out.println( hi2());
System.out.println( hi2());
return new Hi1();
}
@Bean
public Hi2 hi2() {
return new Hi2();
}
}
- lite输出:
com.renxl.demo.Hi2@12ae75f1
com.renxl.demo.Hi2@6eeb15f9
@Component
public class ConfigClass {
@Bean
public Hi1 hi1() {
System.out.println( hi2());
System.out.println( hi2());
return new Hi1();
}
@Bean
public Hi2 hi2() {
return new Hi2();
}
}
full模式区别的实现一ConfigurationClassPostProcessor.postProcessBeanFactory
通过cglib代理完成对full模式的处理
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
// 通过cglib代理完成对full模式的处理
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new importAwareBeanPostProcessor(beanFactory));
}
- enhanceConfigurationClasses的实现目标是找出所有的Configuration注解的配置类并进行增强
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map configBeanDefs = new linkedHashMap<>();
找出所有full模式的配置
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
......删除其他代码
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
通过增强替换了BeanDefinition原来的beanclass
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry entry : configBeanDefs.entrySet()) {
......删除其他代码
if (configClass != null) {
Class> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
beanDef.setBeanClass(enhancedClass);
}
}
}
增强的目的以及实现
目的
- 增强的目的是对所有@bean方法的调用改从spring容器中获取
- 获取的方式区分factorybean和普通bean
| bean | factorybean |
|---|---|
| beanFactory.getBean(beanName, beanMethodArgs) | beanFactory.getBean(beanName) |
- 代理类实现了EnhancedConfiguration
- 代理类拦截点如下BeanMethodInterceptor,BeanFactoryAwareMethodInterceptor
- EnhancedConfiguration是BeanFactoryAware子接口
- 增加一个$$beanFactory属性
private Enhancer newEnhancer(Class> configSuperClass, @Nullable ClassLoader classLoader) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(configSuperClass);
代理类实现了EnhancedConfiguration
enhancer.setInterfaces(new Class>[] {EnhancedConfiguration.class});
enhancer.setUseFactory(false);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
设置一个属性$$beanFactory
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
代理类拦截点如下BeanMethodInterceptor,BeanFactoryAwareMethodInterceptor
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
return enhancer;
}
BeanFactoryAwareMethodInterceptor作用
- 如果是setBeanFactory方法则将beanfactory赋值到$$beanFactory属性
- 前面说过EnhancedConfiguration是BeanFactoryAware子接口,而Aware接口在实例化的过程中会被spring容器自动注入相关目标实例,意味着所有的@Configuration都还有Beanfactory对象
private static class BeanFactoryAwareMethodInterceptor implements MethodInterceptor, ConditionalCallback {
@Override
@Nullable
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
......删除多余代码
Field field = ReflectionUtils.findField(obj.getClass(), BEAN_FACTORY_FIELD);
field.set(obj, args[0]);
}
@Override
public boolean isMatch(Method candidateMethod) {
return isSetBeanFactory(candidateMethod);
}
}
BeanMethodInterceptor完成full模式实现
- 1 通过$$beanFactory属性获取BeanFactoryAwareMethodInterceptor设置的beanfactory
- 2 匹配所有@bean注解方法
- 3 如果是工厂bean,判断是通过cglib还是jdk代理实现,最后调用beanfactory获取bean
- 4 普通bean,通过beanfactory获取bean
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
MethodProxy cglibMethodProxy) throws Throwable {
......删除其他代码
- 1 通过$$beanFactory属性获取BeanFactoryAwareMethodInterceptor设置的beanfactory
ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
- 3 如果是工厂bean,判断是通过cglib还是jdk代理实现,最后调用beanfactory获取bean
return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
}
- 4 普通bean,通过beanfactory获取bean
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
private Object resolveBeanReference(Method beanMethod, Object[] beanMethodArgs,
ConfigurableBeanFactory beanFactory, String beanName) {
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
beanFactory.getBean(beanName));
return beanInstance;
}
@Override
public boolean isMatch(Method candidateMethod) {
- 2 匹配所有@bean注解方法
return (candidateMethod.getDeclaringClass() != Object.class &&
!BeanFactoryAwareMethodInterceptor.isSetBeanFactory(candidateMethod) &&
BeanAnnotationHelper.isBeanAnnotated(candidateMethod));
}
private Object enhanceFactoryBean(final Object factoryBean, Class> exposedType,
final ConfigurableBeanFactory beanFactory, final String beanName) {
......删除其他代码
if (finalClass || finalMethod) {
return createInterfaceProxyForFactoryBean(factoryBean, exposedType, beanFactory, beanName);
}
return createCglibProxyForFactoryBean(factoryBean, beanFactory, beanName);
}
private Object createInterfaceProxyForFactoryBean(final Object factoryBean, Class> interfaceType,
final ConfigurableBeanFactory beanFactory, final String beanName) {
......删除其他代码
省略了jdk代理部分,就留下如果创建对象的关键
return beanFactory.getBean(beanName);
}
private Object createCglibProxyForFactoryBean(final Object factoryBean,
final ConfigurableBeanFactory beanFactory, final String beanName) {
......删除其他代码
省略了cglib代理代码,就留下如果创建对象的关键
return beanFactory.getBean(beanName);
}
}
总结
- full模式对@bean的方法调用通过aop完成,改从beanfactory获取
- lite模式还是直接对原来的方法调用,这也是文首输出不同的原因
- full模式的实现通过MethodInterceptor完成aop
- BeanFactoryAwareMethodInterceptor 通过aware功能实现beanfactory的Aware注入
- BeanMethodInterceptor实现对原方法的拦截,改从beanfactory获取
获取@bean注解注释的方法想要获取的对象



