SpringBoot @Been和@Import

@Bean

在启动类中编写

1
2
3
4
5
6
7
8
9
10
11
12
@SpringBootApplication
public class Demo16Application {
public static void main(String[] args) {
ApplicationContext run = SpringApplication.run(Demo16Application.class, args);
LoaderOptions bean = run.getBean(LoaderOptions.class);
System.out.println(bean);
}
@Bean
public LoaderOptions getLoaderOptions(){
return new LoaderOptions();
}
}

在配置类中编写

在启动类包中创建config文件夹接着在创建配置类

1
2
3
4
5
6
7
@Configuration
public class MyConfig {
@Bean
public LoaderOptions getLoaderOptions(){
return new LoaderOptions();
}
}

@Import

当启动类中的@ComponentScan找不到配置文件时可以用@Import导入

常规用法

在启动类中添加@Import(MyConfig.class),就可以导入配置类,MyConfig为配置类的名字
配置类中的信息与上文的一致,只是路径发生改变,导致@SpringBootApplication无法找到该配置类

ImportSelector接口

新建SelectImport文件在实现ImportSelector,接着在添加配置类的路径

1
2
3
4
5
6
public class SelectImport implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.example.config.MyConfig"};
}
}

启动类中修改@Import中的参数@Import(SelectImport.class)

引入resources中imports文件

在resources文件夹中创建common.imports文件,imports中的信息为配置类的路径,可存放多个配置类
接着将该文件中的信息导入导SelectImport类中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class SelectImport implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
List<String> imports = new ArrayList<>();
InputStream resourceAsStream = SelectImport.class.getClassLoader().getResourceAsStream("common.imports");
BufferedReader br = new BufferedReader(new InputStreamReader(resourceAsStream));
String line = null;
try{
while((line = br.readLine())!= null){
imports.add(line);
}
}catch (IOException e){
throw new RuntimeException(e);
}finally {
if (br!=null){
try{
br.close();
}catch (IOException e){
throw new RuntimeException(e);
}
}
}
return imports.toArray(new String[0]);
}
}

注册条件

@ConditionalOnProperty

配置文件中存在对应的属性,才声明该bean
prefix为Property文件中的student类,name为student中的属性名
当没有Properties的数据传入该bean就不会将该bean带入ioc容器中

1
2
3
4
5
6
7
8
9
@Configuration
public class MyConfig {
@Bean
@ConditionalOnProperty(prefix = "student",name={"name","id"})
@ConfigurationProperties(prefix = "student")
public Student getStudent(){
return new Student();
}
}

@ConditionalOnMissingBean

当不存在当前类型的bean时,才声明该bean
当容器中有Teacher时Student不创建,有前后之分

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class MyConfig {
@Bean
public Teacher getTeacher(){
return new Teacher();
}
@Bean
@ConditionalOnMissingBean(Teacher.class)
@ConfigurationProperties(prefix = "student")
public Student getStudent(){
return new Student();
}
}

@ConditionalOnClass

当前环境存在指定的这个类时,才声明该bean
name未指定类的全类名

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MyConfig {
@Bean
@ConditionalOnClass(name="org.springframework.web.servlet.DispatcherServlet")
public Teacher getTeacher(){
return new Teacher();
}
@Bean
@ConditionalOnMissingBean(Teacher.class)
@ConfigurationProperties(prefix = "student")
public Student getStudent(){
return new Student();
}
}