@Bean的方法是如何保证单例的?如果不需要单例需要怎么配置?为什么需要这么配置
1.如何保证单例
2. 如果不需要单例需要怎么配置
不要单例的话将类上的 @Configuration
注解改为@Component
注解
BeanFactory
1. @Configuration简介
Spring @Configuration 注解介绍
如果加了@Configuration,那么对应的BeanDefinition为full,如果加了@Bean,@Component,@ComponentScan,@Import,@ImportResource这些注解,则为lite。lite和full均表示这个BeanDefinition对应的类是一个配置类。
2.@Configuration一些问题
(1) @Configuration注解的作用是什么,Spring是如何解析加了@Configuration注解的类?
(2) Spring在什么时候对@ComponentScan、@ComponentScans注解进行了解析?
(3) Spring什么时候解析了@Import注解,如何解析的?
(4) Spring什么时候解析了@Bean注解?
3.底层为什么使用cglib
[底层为什么使用cglib]
- 很多人问,为什么要对@Configuration标注的类做cglib加强?一方面BeanFactoryAwareMethodInterceptor在ImportAwareBeanPostProcessor后置处理器调用setBeanFactory填充时会将BeanFactory注入属性“$$beanFactory”,一方面BeanMethodInterceptor这个拦截器可以在访问@Bean注解的方法的时候,保证生成的bean是单例的,具体就是在调用方法时,拦截器中会根据BeanMethod对应的BeanName首先在BeanFactory中进行查找。
- 简单说一下个人理解,也可以参考源码分析:https://www.jb51.net/article/153430.htm
- 1、如果不增强的情况下,@Bean方法A希望在创建A的过程中调用@Bean方法B作为自身属性,那么必然是一个new的新对象B,无法保证单例B的存在,所以cglib后就是为了增加额外的判断保证单例
- 2、cglib加强类的父接口为EnhancedConfiguration,继承了BeanFactoryAware,所以该类现在实现了BeanFactoryAware接口
- 3、BeanFactoryAwareGeneratorStrategy 负责为 cglib的代理类申明 $$beanFactory 字段 用于存放BeanFactory
- 4、BeanFactoryAwareMethodInterceptor 负责拦截ImportAwareBeanPostProcessor中触发的setBeanFactory方法,做一些额外处理并赋值BeanFactory至 $$beanFactory字段。额外操作是什么呢?如果其被加强的原始的类实现了setBeanFactory 则会调用真正的原始类的setBeanFactory 否则只是会给proxy通过反射塞入beanFactory
- 5、BeanMethodInterceptor在访问@Bean注解的方法是,优先从属性$$beanFactory中获取Bean的实例,保证单例
-
CGLIB
创建动态代理是基于继承来是实现的(JDK的动态代理是基于接口实现),因此enhancer.setSupperclass(configSuperClass)
这一行代码,就是为即将产生的代理对象设置父类,同时为产生的代理对象实现EnhancedConfiguration.class
接口,实现该接口的目的,是为了该Configuration
类在实例化、初始化过程中,执行相关的BeanPostProcessor。 - 例如在执行
ImportAwareBeanPostProcessor
后置处理器时,postProcessPropertyValues()
方法,会对EnhancedConfiguration
类进行属性设置,实际就是为EnhancedConfiguration
实现类的beanfactory
属性赋值
(https://blog.csdn.net/z69183787/article/details/104521697)