@Configuration
public class AppConfig {
@Bean
public A a() {
return new A(b());
}
@Bean
public B b() {
return new B();
}
}
上面代码中new A(b());这里面的b()每次调用都是新对象吗?
解析
在@Configuration类中,new A(b())中的b()不会每次都返回新对象。Spring通过CGLIB代理确保@Bean方法返回单例实例,具体原因如下:
1. CGLIB 代理机制
- 代理类:Spring会为
@Configuration类生成CGLIB代理,拦截@Bean方法的调用。 - 单例保证:代理确保多次调用
@Bean方法时返回同一个实例。
2. 代码分析
@Configuration
public class AppConfig {
@Bean
public A a() {
return new A(b()); // 这里的 b() 由代理管理,返回单例
}
@Bean
public B b() {
return new B(); // 单例实例
}
}
b()调用:b()通过代理调用,返回同一个B实例。A的创建:new A(b())中的b()返回的是单例B。
3. 对比 @Component(Lite 模式)
如果去掉@Configuration,改为@Component,b()会直接调用,每次返回新实例:
@Component
public class AppConfig {
@Bean
public A a() {
return new A(b()); // 每次调用 b() 都会创建新实例
}
@Bean
public B b() {
return new B(); // 每次返回新实例
}
}
- 无代理:
b()直接调用,每次返回新对象。
4. 总结
@Configuration:b()通过代理调用,返回单例。@Component:b()直接调用,每次返回新实例。
因此,在@Configuration类中,new A(b())中的b()返回的是单例B对象。