@Import的定义
@Import的源码
1
2
3
4
5
6
7
8
package org.springframework.context.annotation;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}
注解内部只有一个默认属性,并且类型是Class对象数组类型,实际上@Import就是用来把需要定义为Bean的类导入到IOC容器里面。
导入普通类
如何导入
- @Import应该标记在@SpringBootApplication(启动类)、@Configuration(配置类)、@Component(组件类)对应的类上。
@RestController、@Service、@Repository都属于@Component
- 在默认属性中指定需要导入的类的class对象
示例:
1
2
3
4
5
6
7
@SpringBootApplication
@Import(ImportBean.class) // 通过@Import注解把ImportBean添加到IOC容器里面去
public class MyBatisApplication {
public static void main(String[] args) {
SpringApplication.run(MyBatisApplication.class, args);
}
}
引入配置类(@Configuration修饰的类)
达到的效果
能够使得配置类生效,当然在启动类的根目录或子目录下,@Configuration标注的类会自动生效,使用@Import的场景往往是不在启动类根目录下,比如自定义Starter会经常用到
如何使用
与导入普通时一样,依然需要满足第一点,在第二点时就导入对应的配置类的class对象
示例:
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
@Configuration(proxyBeanMethods = false)
@Import({ // import了两个
XXXDataConfiguration.XXXPartOneConfiguration.class,
XXXDataConfiguration.XXXPartTwoConfiguration.class
})
public class XXXDataAutoConfiguration {
}
public class XXXDataConfiguration {
@Configuration(proxyBeanMethods = false)
static class XXXPartOneConfiguration {
@Bean
@ConditionalOnMissingBean
public BeanForIoc beanForIoc() {
return new BeanForIoc();
}
}
@Configuration(proxyBeanMethods = false)
static class XXXPartTwoConfiguration {
/**
* 省略了@Bean的使用
*/
}
}
导入ImportSelector的实现类
达到的效果
可以把ImportSelector接口selectImports()方法返回的Class名称都定义为bean。
ImportSelector接口源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public interface ImportSelector {
/**
* Select and return the names of which class(es) should be imported based on
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
* @return the class names, or an empty array if none
*/
String[] selectImports(AnnotationMetadata importingClassMetadata);
@Nullable
default Predicate<String> getExclusionFilter() {
return null;
}
}
在实现类中,selectImports()会返回需要导入容器中的类名
静态导入
示例:
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
26
27
28
29
/**
* XXXConfigurationSelector一定要配合@Import使用
*/
public class XXXConfigurationImportSelector implements ImportSelector {
@Override
@NonNull
public String[] selectImports(@NonNull AnnotationMetadata importingClassMetadata) {
// 把XXX对应的类,定义为Bean
return new String[]{XXX.class.getName()};
}
}
/**
* 注意 @Import(XXXConfigurationImportSelector.class)
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(XXXConfigurationImportSelector.class)
public @interface EnableXXX {
}
@SpringBootApplication
@EnableXXX // 使之生效
public class MyBatisApplication {
public static void main(String[] args) {
SpringApplication.run(MyBatisApplication.class, args);
}
}