Spring Boot容器的使用
组件添加
- @Configuration
Spring Boot不再使用beans.xml的方式进行bean对象的注入,而是可以使用@Configuration注解的方式来将一个类声明成配置类
,该类的作用就相当于beans.xml配置文件。
@Configuration
public class Configs {
}
- @Bean
在使用@Configuration注解的配置类中可以在方法上使用@Bean注解,将该方法的返回对象注入容器中。
@Configuration
public class Configs {
@Bean
public User getUser() {
return new User();
}
}
方法名就是bean对象的id属性值
,如果使用getXxx的命名方式就是后面的xxx,与属性的获取规则一致。也可以在@Bean注解中指定id属性的值。这种方式配置是单例对象。
组件代理机制
@Configuration中的属性proxyBeanMethods
,其默认值为true,此时即使是从外部新建一个Configs类调用getUser方法得到User对象任然是同一个对象。
如果设置为false的话该配置类中配置的bean对象就不是代理对象,此时如果从外部中调用Configs类中的getUser方法,获取的就不是同个对象。
- proxyBeanMethods=true
Configs = cn.net.smrobot.config.Configs$$EnhancerBySpringCGLIB$$6fefa48e@7d1b26cd
# 该对象就是一个代理对象
- proxyBeanMethods=false
Configs = cn.net.smrobot.config.Configs@14565b64
# 可见只是一个普通的对象
因此如果设置为true,那么只要是通过代理对象获取到的其他对象,都会从spring容器中获取同一个单例对象。
代理模式
Full模式,proxyBeanMethods=true,即每一次都会从Spring容器中获取同一个对象。
Lite模式,proxyBeanMethods=false,轻量级模式。如果配置类中的组件并没有相互依赖关系,就设置为这个。
最佳实战:
- 配置组件之间无依赖关系用lite模式加速容器启动过程,减少判断。
- 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式。
- @Import
可以往配置类
中导入组件。导入的默认的组件的名字为全限定类名
。例如
@Import({User.class, Person.class}) // 会往配置类中导入User对象和Person对象
@Configuration
public class Config{
// 使用@Autowired注解进行注入
@Autowired
private User user;
@Autowired
private Person person;
}
- @ImportResource
将bean.xml中的bean配置重新解析放入容器中。相当于加载bean.xml配置文件。
@Configuration
// 重新解析bean文件
@ImportResource("classpath:bean.xml")
public class Config{
// 也可以使用@Autowired注解进行注入
@Autowired
private User user;
}
- @ConfigurationProperties
该注解可以将核心配置文件中的对象的值设置到对应的属性中。
// 也要将该类配置到容器中
@Component
// prefix前缀指的是配置文件的第一个键
@ConfigurationProperties(prefix = "my-car")
public class Car {
private String brand;
private Integer price;
}
my-car.brand = BMW
my-car.price = 1000000
这样就在容器中注册一个对象为
Car(brand=BMW, price=1000000)
注意:这里的my-car不要使用驼峰命名法,Spring Boot中的命名规范是分隔符
的方式,使用驼峰命名会报错。
- @EnableConfigurationProperties
该注解的作用和上面的注解作用类似,如果我们在实体类中没有使用@Component将该对象配置到容器中,而仅仅使用@ConfigurationProperties注解是不行的(在IDEA中会报红)。但是如果真的不想写的话可以在配置类中使用@EnableConfigurationProperties(class)来开启对应的属性配置功能。
@Data
//@Component
@ConfigurationProperties(prefix = "my-car")
public class Car {
private String brand;
private int price;
}
// Configs.java
@EnableConfigurationProperties(Car.class)
public class Configs {
}
注意以这种方式配置到容器中的对象名称为:
prefix+该对象的全限定类名
- @Conditional
条件装配注解,当满足conditional指定的条件时,进行组件的注入。该注解下面派生了很多其他具体条件的注解。在Spring Boot底层的自动配置中经常被使用到。
@Configuration
// 如果容器中没有person组件,下面类就不生效
@ConditionalOnBean(name = {"person"})
public class Config{
@ConditionalOnBean(name = "xxx") // 用在方法上也行
@Bean
public Person getPerson() {
return new Person();
}
}
// 在启动类中Application.java中取出Config对象
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(Application.class, args);
// 会报错
Configs configs = run.getBean("configs", Configs.class);
}
@ConditionalOnBean用来判断指定名称的对象是否在容器中,如果不在的话被注解的主体(类型或者方法)就不起作用。
更多的条件注解可以在org.springframework.boot.autoconfigure.condition包
中找到。