【Spring源码解析】组件注册-@Import注解
@Import注解
@Import 注解支持导入普通 java 类,并将其声明成一个bean。主要用于将多个分散的 java config 配置类融合成一个更大的 config 类。
@Import 三种使用方式
- 直接导入普通的 Java 类。
- 配合自定义的 ImportSelector 使用。
- 配合 ImportBeanDefinitionRegistrar 使用。
Configuration方式
- 创建一个普通类
1 2 3 4 5
| public class Hi { public void sayHello() { System.out.println("Hello World"); } }
|
- 创建一个配置类,里面没有显式声明任何的 Bean,然后将刚才创建的 Hi 导入
1 2 3 4
| @Import(Hi.class) @Configuration public class HiConfig { }
|
- 创建controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @RestController public class HiController { @Autowired Hi hi;
@GetMapping("/hi") public Object hi() { hi.sayHello(); return "hi"; } }
|
annotation方式
创建EnableHiConfig
1 2 3 4 5 6
| @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({Hi.class}) public @interface EnableHiConfig { }
|
在application中加入注解@EnableHiConfig然后controller中即可调用
1 2 3 4 5 6 7
| @EnableHiConfig @SpringBootApplication public class IdcMpApplication { public static void main(String[] args) { SpringApplication.run(IdcMpApplication.class, args); } }
|
ImportSelector
如果定义太多注解,那么在main方法上要添加太多注解…因此使用ImportSelector
ImportSelector 是一个接口,该接口中只有一个 selectImports 方法,用于返回全类名数组。所以利用该特性我们可以给容器动态导入 N 个 Bean。
因为这两个bean都是通过@Enable类型注解来将配置类注册到IOC容器中,所以我们现在要做的就是将这两个bean一次性都注册到IOC容器中。在Spring中,要将多个类进行注册,可以使用selector的方式。
创建HiSelector
1 2 3 4 5 6 7 8
| public class HiSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata annotationMetadata) { return new String[]{ Hi.class.getName() }; } }
|
创建EnableHiConfig
1 2 3 4 5 6
| @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({HiSelector.class}) public @interface EnableHiConfig { }
|
在application中加入注解@EnableHiConfig然后controller中即可调用
ImportBeanDefinitionRegistrar
1 2 3 4 5 6 7
| public class HiImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { BeanDefinition beanDefinition = new RootBeanDefinition(Hi.class); registry.registerBeanDefinition("hi", beanDefinition); } }
|
1 2 3 4 5 6
| @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({HiImportBeanDefinitionRegistrar.class}) public @interface EnableHiConfig { }
|
springboot源码中大多这种方式注入
IOC
IOC是一种编程思想, 由主动的编程改成被动的接收。
所谓IOC一句话搞定, 对象由spring来创建、管理、装配。
最后
本文到此结束,感谢阅读。如果您觉得不错,请关注公众号【当我遇上你】,您的支持是我写作的最大动力。