SpringBoot2学习笔记之容器功能
1、组件添加
1.1、@Configuration
- 基本使用
- Full模式与Lite模式
- 示例
- 实践
- 配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断。
- 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式。
配置类:
1 /** 2 * 1. @Configuration 告诉SpringBoot这是一个配置类 3 * 2. @Bean 配置类中使用@Bean标注在方法上给容器注册组件,默认为单实例 4 * 3. proxyBeanMethods:代理Bean方法 5 * 3.1 Full(proxyBeanMethods = true) 保证每个@Bean方法被调用多少次返回的组件都是单实例的 6 * 3.2 Lite(proxyBeanMethods = false) 每个@Bean方法被调用多少次返回的组件都是新创建的 7 * 组件依赖必须使用Full模式。其他默认是否则使用Lite模式 8 * 4.适用场景 9 * 4.1 组件依赖 10 */ 11 @Configuration(proxyBeanMethods = true) 12 public class MyConfig { 13 14 /** 15 * @Bean 向容器中添加组件,以方法名作为组件id,返回类型为组件类型,返回的值,就是组件在容器中的实例 16 * 外部无论对配置类中的这个组件注册方法注册多少遍,获取的都是之前注册到容器中的单实例 17 * @return 18 */ 19 @Bean 20 public User userA(){ 21 return new User("zhangsan", 3); 22 } 23 24 @Bean("tom") 25 public Pet tomcatPet() { 26 return new Pet("tomcat"); 27 } 28 }
配置类测试
/** * 称为主程序类 * 告诉SpringBoot这是一个SpringBoot应用 */ @SpringBootApplication public class MainApplication { public static void main(String[] args) { //1.返回IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); //2.查看容器里的组件 String[] beanDefinitionNames = run.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { System.out.println("组件名称: " + beanDefinitionName); } //3.从容器中获取组件 Pet tom01 = run.getBean("tom", Pet.class); Pet tom02 = run.getBean("tom", Pet.class); System.out.println("tom01等于tom02吗? " + (tom01 == tom02)); //4. cn.mxz.boot.config.MyConfig$$EnhancerBySpringCGLIB$$b24b3179@1d8e2eea MyConfig bean = run.getBean(MyConfig.class); System.out.println("MyConfig组件: " + bean); /** * 1.如果@Configuration(proxyBeanMethods = true)代理对象调用方法,SpringBoot总会检查这个组件是否已经存在于容器中, * 要保持组件的单实例 */ User user = bean.userA(); User user1 = bean.userA(); System.out.println("user等于user1吗? " + (user == user1)); } } ======控制台输出====== ...... 组件名称: org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration 组件名称: characterEncodingFilter 组件名称: localeCharsetMappingsCustomizer 组件名称: org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration 组件名称: multipartConfigElement 组件名称: multipartResolver 组件名称: spring.servlet.multipart-org.springframework.boot.autoconfigure.web.servlet.MultipartProperties 组件名称: org.springframework.aop.config.internalAutoProxyCreator tom01等于tom02吗? true MyConfig组件: cn.mxz.boot.config.MyConfig$$EnhancerBySpringCGLIB$$b24b3179@1d8e2eea user等于user1吗? true
1.2、@Import
配置类:
1 /** 2 * 3 * @Import({User.class, DBHelper.class}) 给容器自动创建出这两个类型的组件,默认的组件名字就是组建的全类名 4 */ 5 @Import({User.class, DBHelper.class}) 6 @Configuration(proxyBeanMethods = true) 7 public class MyConfig { 8 9 10 }
配置类测试
1 @SpringBootApplication 2 public class MainApplication { 3 public static void main(String[] args) { 4 //1.返回IOC容器 5 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); 6 7 String[] beanNamesForType = run.getBeanNamesForType(User.class); 8 for (String s : beanNamesForType) { 9 System.out.println(s); 10 } 11 12 DBHelper bean1 = run.getBean(DBHelper.class); 13 System.out.println(bean1); 14 } 15 } 16 ======控制台输出====== 17 cn.mxz.boot.bean.User 18 userA 19 ch.qos.logback.core.db.DBHelper@55f45b92
1.3、@Conditional
条件装配,满足@Conditional指定的条件,则进行组件注入。
- 调用树

2.@ConditionalOnBean示例,也可将该注解标注在MyConfig类上。
1 @Import({User.class, DBHelper.class, MyImportSelector.class}) 2 @Configuration(proxyBeanMethods = true) 3 public class MyConfig { 4 5 /** 6 * @Bean 向容器中添加组件,以方法名作为组件id,返回类型为组件类型,返回的值,就是组件在容器中的实例 7 * 外部无论对配置类中的这个组件注册方法注册多少遍,获取的都是之前注册到容器中的单实例 8 * @return 9 */ 10 @ConditionalOnBean(name = "tom") 11 @Bean 12 public User userA(){ 13 return new User("zhangsan", 3); 14 } 15 16 // @Bean("tom") 17 public Pet tomcatPet() { 18 return new Pet("tomcat"); 19 } 20 } 21 22 23 ======调用测试====== 24 25 @SpringBootApplication 26 public class MainApplication { 27 public static void main(String[] args) { 28 //1.返回IOC容器 29 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); 30 31 32 boolean tom = run.containsBean("tom"); 33 System.out.println("容器中存在Tom组件吗? " + tom); 34 35 boolean userA = run.containsBean("userA"); 36 System.out.println("容器中存在userA组件吗? " + userA); 37 } 38 39 } 40 41 ======控制台输出===== 42 43 容器中存在Tom组件吗? false 44 容器中存在userA组件吗? false
1.3、配置文件导入注解@ImportResource
1.4、配置属性绑定注解@ConfigurationProperties
1.4.1 @ConfigurationProperties + @Component
1 @Component 2 @ConfigurationProperties(prefix = "mycar") 3 public class Car { 4 5 private String brand; 6 private Integer price; 7 8 public String getBrand() { 9 return brand; 10 } 11 12 public void setBrand(String brand) { 13 this.brand = brand; 14 } 15 16 public Integer getPrice() { 17 return price; 18 } 19 20 public void setPrice(Integer price) { 21 this.price = price; 22 } 23 24 @Override 25 public String toString() { 26 return "Car{" + 27 "brand='" + brand + '\'' + 28 ", price=" + price + 29 '}'; 30 } 31 } 32 33 ======application.properties参数配置====== 34 35 mycar.brand=BMW 36 mycar.price=100
1.4.2 @EnableConfigurationProperties + @ConfigurationProperties
1 /** 2 * @EnableConfigurationProperties 开启Car的配置绑定功能,并把Car自动注入到容器当中 3 */ 4 @Configuration(proxyBeanMethods = true) 5 @EnableConfigurationProperties(Car.class) 6 public class MyConfig { 7 8 } 9 10 ================== 11 @ConfigurationProperties(prefix = "mycar") 12 public class Car { 13 14 private String brand; 15 private Integer price; 16 17 public String getBrand() { 18 return brand; 19 } 20 21 public void setBrand(String brand) { 22 this.brand = brand; 23 } 24 25 public Integer getPrice() { 26 return price; 27 } 28 29 public void setPrice(Integer price) { 30 this.price = price; 31 } 32 33 @Override 34 public String toString() { 35 return "Car{" + 36 "brand='" + brand + '\'' + 37 ", price=" + price + 38 '}'; 39 } 40 }
。

浙公网安备 33010602011771号