“lite”@Bean与"Full"@Configuration
我们通常使用@Component和@Configuration来注册Bean。
当@Bean方法在没有使用@Configuration注释的类中声明时,它们被称为在“lite”模式下处理。在@Component中声明的Bean方法,甚至在普通的旧类中声明的Bean方法,都被认为是“lite”。
@Bean方法将在@Configuration类中声明,以确保始终使用“full”模式,并因此将交叉方法引用重定向到容器的生命周期管理。这可以防止通过常规Java调用意外调用相同的@Bean方法,这有助于减少在“lite”模式下操作时难以跟踪的细微bug
“Full”@Configuration中的@Bean会被CGLIB代理,spring会拦截该方法的执行,在默认单例情况下,容器中只有一个Bean,所以我们多次调用也只有一个对象。而lite Bean mode中的@Bean不会被CGLIB代理,会根据普通的java语义进行调用,会导致有多个对象。
注意:被CGLIB的方法是不能被声明为private和final的,因为CGLIB是通过生成子类来实现代理的,而private和final方法是不能被子类override的,也就是说Full@Configuration模式下,@Bean方法是不能被声明为private 和 final的,否则在启动时spring会直接报错。
一般@Configuration会和@Bean合用,若@Bean注解没有用在@Configuration注解下,比如用在@Component下,那么此时就会被"lite模式"处理。
@Configuration
public class BeanConfig{
@Bean
public Car car(){
return new Car();
}
@Bean Foo foo(){
return new Foo(car());
//因为Full @Configuration被CGLIB代理,交由spring代理生命周期,所以可以调用本类中的@Bean方法作为依赖。
}
}