springboot 注册 bean
都是 spring 支持的,@Import 我也是从 spring 的文章张直接复制出来的,那边文章详细解释了 bean 的方方面面,感兴趣可以去看
@Configuration、@Bean
相当于 spring 的配置文件,spring 在配置文件中可以配置 bean,用注解方式就是这样的
// 这个类也会作为一个 bean
@Configuration
public class MyConfig {
// 方法名就是 bean 唯一标识
@Bean
public User user(){
User user = new User();
user.setUsername("Marry");
user.setId(12345L);
return user;
}
}
要让代码有语义,这种方式可以配置 bean,但是 @Configuration 的语义是代替 spring 的配置文件,如果只是想单纯配置一个 bean 其实这种方式并不清晰
如果只是单纯想配置一个 bean 使用 @Component 方式会更好
@Component
@Component
public class User {
private Long id;
private String username;
// getter setter
}
@Service、@Repository、@Controller 也是注册 bean,但是语义上不同(和上面的 @Configuration 一样,虽然都已配置 bean,但是还是建议符合语义的去配置)
@Import
有三种用法,导入的 bean 的唯一 id 是类的权限定名,spring 的文章有说这个,感兴趣可以自行查询 spring 的方方面面
@ImportResource
导入一个 spring bean 的 xml 文件,把里面用 xml 方式配置的 bean 导入进来
老项目可能还是 srping xml 方式,里面很多 bean,或者很多 bean 的配置文件,总之很多 bean,懒得翻译成注解,直接导入
@EnableConfigurationProperties
用于绑定配置文件和 java 对象,要配合 @ConfigurationProperties 来使用,举个例
-
创建一个 java 对象,用于接收配置文件的配置
@Configuration // 当前配置类也要注册到 spring 容器 @PropertySource("classpath:myApplication.yml") // 指定自定义配置文件位置和名称,如果不指定就是主配置文件(application.yaml 或 application.properties) @ConfigurationProperties(prefix = "person.test") // 配置文件 person.test 的配置绑定到当前类的属性上 @Data // lombok public class MyConfig { private int id; private String name; }
-
配置文件
# 会与绑定 MyConfig.id person.test.id=101 # 会与绑定 MyConfig.name person.test.name=lisi
-
启动类使用注解 @EnableConfigurationProperties
@EnableConfigurationProperties(MyConfig.class) @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(Boot2021Application.class, args); } }
-
如果想要配置文件中配置属性的时候自动提示,要导入一个依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency> <!-- 打成的 jar 中再排除,因为只是开发更直观,其实并没有也不影响 --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build>
@Conditional 条件装配
-
派生了很多注解,很容易顾名思义
-
举个 spring 批处理的条件配置
@Configuration(proxyBeanMethods = false) // true(默认):会使用 cglip 生成代理类,false:不生成代理类。作用是当 @Configuration 有很多 @Bean 的时候优化性能 @ConditionalOnClass({ JobLauncher.class, DataSource.class }) // 当项目中中存在 JobLauncher、DataSource 类时才配置下面所有 @Bean 方式的 bean @AutoConfigureAfter(HibernateJpaAutoConfiguration.class) // 当 HibernateJpaAutoConfiguration 类型的 bean 配置完后,配置当前 bean @ConditionalOnBean(JobLauncher.class) // 当存在 JobLauncher 这种类型的 bean 时才配置当前 bean @EnableConfigurationProperties(BatchProperties.class) // 自定义配置类,上面刚说了 @Import(BatchConfigurerConfiguration.class) // 注册一个 BatchConfigurerConfiguration 类型的 bean public class BatchAutoConfiguration { @Bean @ConditionalOnMissingBean // JobLauncherApplicationRunner 类型的 bean 不存在时才注册 @ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true) public JobLauncherApplicationRunner jobLauncherApplicationRunner(JobLauncher jobLauncher, JobExplorer jobExplorer, JobRepository jobRepository, BatchProperties properties) { ... } @Bean @ConditionalOnMissingBean(ExitCodeGenerator.class) // ExitCodeGenerator 类型的 bean 不存在才注册 JobExecutionExitCodeGenerator public JobExecutionExitCodeGenerator jobExecutionExitCodeGenerator() { return new JobExecutionExitCodeGenerator(); } ... }
-
自定义条件
实现 Condition 接口,复写 matches 方法,当条件返回真才注册 bean
// 这个就不用加入容器了 public class EvenWeekDayCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { // 1234567,星期天是 7 不是 0 int dayOfWeek = LocalDate.now().getDayOfWeek().getValue(); return dayOfWeek % 2 == 0; } }
使用条件配置 bean
@Component public class MyBean3 { /** * 如果是周二、周四、周六 就注册 User */ @Conditional(EvenWeekDayCondition.class) @Bean public User user(){ return new User(); } }