spring-boot中@Configuration是怎么实现@Bean方法注入的

其实这个是由spring-context实现的

我们知道在spring中可以使用@Configuration注解标记的类来代替传统的xml配置,然后用@Bean注解标记方法代替<bean>标签

在@Configuration注解标记的类中如果bean有依赖我们可以这样写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* @author xizhou
* @date 2021/6/3 22:53
*/
@Configuration
public class TestConfiguration {

@Bean
public BeanA beanA(){
return new BeanA();
}


@Bean
public BeanB beanB(){
return new BeanB(beanA());
}
}

BeanB 依赖BeanA,然后在上面的beanB()方法里面直接写调用 beanA()方法就行了.

直观来看是不是觉得会调用beanA()方法去生成一个BeanA对象。但是如果是这样的话,就和上面的beanA()方法注入到springIOC容器的对象不是同一个了,这明显是不正确的。

那或者应该是spring对这个beanB()方法里面的beanA()方法调用做了AOP处理,然后就可以和上面的beanA()方法获取到同一个对象

但是我们想到在spring AOP中有个经典的this问题,上面这样不就是 AOP this问题吗?那spring是怎么实现代理的呢?
挠头.gif (240×240) (xyz327.cn)

答案就在org.springframework.context.annotation.ConfigurationClassPostProcessor类中

我们直接看org.springframework.context.annotation.ConfigurationClassPostProcessor#enhanceConfigurationClasses方法
@Configuration标记的类有下面的操作

1
2
3
4
Class<?> configClass = beanDef.getBeanClass();
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);

beanDef.setBeanClass(enhancedClass);

我们可以看到spring是对整个类做了一个AOP然后把代理后的类作为BeanClass 就这样在上面beanB()方法中调用beanA()方法其实是调用的经过代理够的beanA()方法.然后也就没有AOP this问题了