@Configuration
标记上该注解的类,表示该类是配置类,告诉SpringBoot这是一个配置类 == 配置文件,并且放入容器中。
- 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
- 2、配置类本身也是组件
- 3、proxyBeanMethods:代理bean的方法
- Full(proxyBeanMethods = true)(保证每个@Bean方法被调用多少次返回的组件都是单实例的)(默认)
- Lite(proxyBeanMethods = false)(每个@Bean方法被调用多少次返回的组件都是新创建的)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
boolean proxyBeanMethods() default true;
}
@Bean
一般标记在方法上, 给容器添加一个组件,方法名为组件的id, 返回类型为组件的类型,返回的值(对象)作为组件在容器的实例。
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
@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");
}
}
最佳实战
如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
- 配置 类组件之间无依赖关系,用Lite模式加速容器启动过程,减少判断
- 配置 类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式(默认)
@Import 导入组件
利用@Import 注解导入组件
- @Import({User.class, DBHelper.class})给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
public class MyConfig {
}
- ImportSelector 接口
实现 ImportSelector 接口 再通过
@Import(value = UseImportSelector.class)
导入指定组件(selectImports方法返回的String数组)SpringBoot 的自动装配 也是通过这种方式导入需要的组件
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
/**
* 用户Bean选择器配置类
*/
public class UseImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata){
// 指定User类的全限类名
return new String[]{"com.hstc.User"};
}
}
- ImportBeanDefinitionRegistrar 接口
public class UserImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 创建User类型的Bean的定义
BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
// 将创建的UserBean定义注册到SpringRegistry中,其名称为user
registry.registerBeanDefinition("user", beanDefinition);
}
}
在 启动类或配置类上 使用:
@Import(value = UserImportBeanDefinitionRegistrar.class)
@Conditional条件装配
条件装配:满足Conditional指定的条件,则进行组件注入
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(name = "tom")//没有tom名字的Bean时,MyConfig类的Bean才能生效。
public class MyConfig {
@Bean
public User user01(){
User zhangsan = new User("zhangsan", 18);
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom22")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
@ImportResource导入Spring配置文件
比如,公司使用bean.xml文件生成配置bean,然而你为了省事,想继续复用bean.xml,@ImportResource粉墨登场。
bean.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans ...">
<bean id="haha" class="com.lun.boot.bean.User">
<property name="name" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>
<bean id="hehe" class="com.lun.boot.bean.Pet">
<property name="name" value="tomcat"></property>
</bean>
</beans>
使用方法:
@ImportResource("classpath:beans.xml")
public class MyConfig {
...
}
@ConfigurationProperties配置绑定
这个注解用于从配置文件中取值
该注解可以标注在类上 也可以标注在方法上.
- @Component + @ConfigurationProperties
假设有配置文件application.properties 或 .yml
boot.name=zs
boot.age=10
只有在容器中的组件,才会拥有SpringBoot提供的强大功能
@Component
@ConfigurationProperties(prefix = "boot")
public class Person {
...
}
-
@EnableConfigurationProperties + @ConfigurationProperties
@EnableConfigurationProperties
- 开启Person配置绑定功能
- 把这个Person这个组件自动注册到容器中
@EnableConfigurationProperties(Person.class)
public class MyConfig {
...
}
@ConfigurationProperties(prefix = "boot")
public class Person {
...
}
总结 @ConfigurationProperties 注解能够很轻松的从配置文件中取值,优点如下:
- 支持批量的注入属性,只需要指定一个前缀 prefix
- 支持复杂的数据类型,比如 List 、 Map
- 对属性名匹配的要求较低,比如 user-name , user_name , userName , USER_NAME 都可以取值
- 支持JAVA的JSR303数据校验
@SpringBootApplication
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
...
}
@SpringBootConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
@Configuration
代表当前是一个配置类。
@ComponentScan
指定扫描哪些Spring注解。
@EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}