一. ImportSelector实现bean的动态装载
1. 自定义类实现ImportSelector接口,重写selectImports接口,通知spring需要加载的配置类,完成bean的自动装载
/**
* bean的动态装载之importSelector - 自定义类=
*/
public class ZswImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
System.out.println("ZswImportSelector ============== selectImports");
return new String[] { ZswImportSelectorConfiguration.class.getName() };
}
}
/**
* 自定义配置类 --- 用于加载importselector包内的Demo7对象
*/
@ComponentScan("com.test.wei.biz.beanautowired.importselector")
@Configuration
public class ZswImportSelectorConfiguration {
}
@Component
public class Demo7 {
}
2. 启动类上不加任何注解,Demo7未装载,获取对象时报错:
/**
* springboot 启动类 默认扫描范围: 其所在的包及其子包下
*/
@SpringBootApplication
public class BeanAutowiredTestApplication {
public static void main(String[] args) {
System.out.println("BeanAutowiredTestApplication 启动");
ConfigurableApplicationContext context = SpringApplication.run(BeanAutowiredTestApplication.class, args);
System.out.println("从spring容器中获取对象 Demo7: " + context.getBean(Demo7.class));
}
}
3. 启动类上加注解@Import(ZswImportSelector.class):
/**
* springboot 启动类 默认扫描范围: 其所在的包及其子包下
*/
@Import(ZswImportSelector.class) // 通过ImportSelector --- 实现bean的自动装载
@SpringBootApplication
public class BeanAutowiredTestApplication {
public static void main(String[] args) {
System.out.println("BeanAutowiredTestApplication 启动");
ConfigurableApplicationContext context = SpringApplication.run(BeanAutowiredTestApplication.class, args);
System.out.println("从spring容器中获取对象 Demo7: " + context.getBean(Demo7.class));
}
}
二. ImportBeanDefinitionRegistrar实现bean的动态装载
1. 自定义类实现ImportBeanDefinitionRegistrar解口,重写registerBeanDefinitions方法,完成特定对象的装载
/**
* bean的动态装载之ImportBeanDefinitionRegistrar, 仿照@EnableFeignClients的写法
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(ZswImportBeanDefinitionRegistrar.class)
public @interface EnableZswRegistrar {
}
public class ZswImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClassName(Demo9.class.getName());
registry.registerBeanDefinition("Demo9", beanDefinition);
}
}
@Component
public class Demo9 {
}
2. 启动类上不加任何注解,Demo9未装载,获取对象时报错:
/**
* springboot 启动类 默认扫描范围: 其所在的包及其子包下
*/
@SpringBootApplication
public class BeanAutowiredTestApplication {
public static void main(String[] args) {
System.out.println("BeanAutowiredTestApplication 启动");
ConfigurableApplicationContext context = SpringApplication.run(BeanAutowiredTestApplication.class, args);
System.out.println("从spring容器中获取对象 Demo8: " + context.getBean(Demo8.class));
System.out.println("从spring容器中获取对象 Demo9: " + context.getBean(Demo9.class));
}
}
3. 启动类上加注解
@EnableZswRegistrar // 通过ImportBeanDefinitionRegistrar --- 实现bean的自动装载
@SpringBootApplication
public class BeanAutowiredTestApplication {
public static void main(String[] args) {
System.out.println("BeanAutowiredTestApplication 启动");
ConfigurableApplicationContext context = SpringApplication.run(BeanAutowiredTestApplication.class, args);
System.out.println("从spring容器中获取对象 Demo8: " + context.getBean(Demo8.class));
System.out.println("从spring容器中获取对象 Demo9: " + context.getBean(Demo9.class));
}
}
三. 打开两个注解重新测试
/**
* springboot 启动类 默认扫描范围: 其所在的包及其子包下
*/
@EnableZswRegistrar // 通过ImportBeanDefinitionRegistrar --- 实现bean的自动装载
@Import(ZswImportSelector.class) // 通过ImportSelector --- 实现bean的自动装载
@SpringBootApplication
public class BeanAutowiredTestApplication {
public static void main(String[] args) {
System.out.println("BeanAutowiredTestApplication 启动");
ConfigurableApplicationContext context = SpringApplication.run(BeanAutowiredTestApplication.class, args);
System.out.println("从spring容器中获取对象 Demo8: " + context.getBean(Demo8.class));
System.out.println("从spring容器中获取对象 Demo7: " + context.getBean(Demo7.class));
System.out.println("从spring容器中获取对象 Demo9: " + context.getBean(Demo9.class));
}
}