1.@Configuration作用
- 相当于一个配置文件,告诉SpringBoot这是一个配置类,作为bean的定义源
- 允许同一类中的@Bean方法来定义bean之间的依赖关系(仅限于Full模式)
2.proxyBeanMethods: 代理bean方法
1. Full(proxyBeanMethods = true)(保证每个@Bean方法被调用多少次返回的组件都是单实例的)(默认)
2. Lite(proxyBeanMethods = false)(每个@Bean方法被调用多少次返回的组件都是新创建的)
3. 如果不同Bean直接有依赖则必须使用代理模式
4. 代码
/**
* 1 配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
* 2 配置类本身也是组件
* 3 proxyBeanMethods:代理bean的方法
* Full(proxyBeanMethods = true)(保证每个@Bean方法被调用多少次返回的组件都是单实例的)(默认)
* Lite(proxyBeanMethods = false)(每个@Bean方法被调用多少次返回的组件都是新创建的)
* 4 加入容器后名称默认为类名驼峰
*/
@Configuration(proxyBeanMethods = true) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
/**
* Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
* @return
*/
@Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了Pet组件
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
3.在容器中测试@Configuration的两种模式
- 代码
@SpringBootApplication
public class ReApplication {
public static void main(String[] args) {
// 1 返回IOC容器 通过SpringApplication.run(启动类.class)
ConfigurableApplicationContext run = SpringApplication.run(ReApplication.class);
// 2 查看容器的组件
String[] names = run.getBeanDefinitionNames();
for(String name : names){
System.out.println(name);
}
// 3 查看代理bean
MyConfig myConfig = run.getBean(MyConfig.class);
System.out.println("MyConfig is " + myConfig);
// 4 调用bean代理方法 检测
User user01 = myConfig.user01();
User user02 = myConfig.user01();
System.out.println("User是否为单例 :" + (user01 == user02) );
}
}
-
结果:
-
当设置为代理时 proxyBeanMethods = true
MyConfig is com.yang.respringboot.re.config.MyConfig$$EnhancerBySpringCGLIB$$d0138dc1@383f3558 User是否为单例 :true 可以看到容器返回了唯一的单例bean,并且MyConfig是被spring增强了
-
但不设置为代理时 proxyBeanMethods = false
MyConfig is com.yang.respringboot.re.config.MyConfig@61942c1 User是否为单例 :false 可以看到此时调用方法返回的是新的对象,且MyConfig没有被增强
-
3.总结
- @Configuration 默认开启代理此时返回单例,及每次容器都会为我们检测是否是单例
- proxyBeanMethods = false 时,每次调用都会返回新的对象
- @Configuration 内也可以使用 @Value @Autowired等注解
- 与Compent相比,差别在于开启代理时@Configuration会发回单例bean,而@Compent每次会返回新的bean
- 如果bean间存在依赖那么一定要是单例bean