spring boot启动的时候会自动扫描启动类上@Enable开头的注解,然后我们可以给@EnableXXX加上注解@Import,导入实现了ImportSelector或ImportBeanDefinitionRegistrar的类
-
新建spring-boot-stater工程:myTest2-spring-boot-starter
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.5.RELEASE</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.test</groupId>
<artifactId>myService</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
@Enable开头的注解:@EnableMyTest
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
public @interface EnableMyTest {
boolean value() default true;
}
实现了ImportSelector的类:根据@EnableMyTest的value值注入TestService1到spring IOC容器中
public class MyImportSelector implements ImportSelector , BeanFactoryAware {
private BeanFactory beanFactory;
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
importingClassMetadata.getAnnotationTypes().forEach(System.out::println);
System.out.println(beanFactory);
AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableMyTest.class.getName())
);
//在这里可以拿到所有注解的信息,可以根据不同注解的和注解的属性来返回不同的class,
Object object = annotationAttributes.get("value");
boolean isTrue=object==null?false:Boolean.parseBoolean(object.toString());
if (isTrue){
return new String[]{TestService1.class.getName()};
}
// 从而达到开启不同功能的目的
return new String[0];
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory=beanFactory;
}
}
实现了ImportBeanDefinitionRegistrar的类:根据@EnableMyTest的value值注入TestService2到spring IOC容器中
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(
importingClassMetadata.getAnnotationAttributes(EnableMyTest.class.getName())
);
//在这里可以拿到所有注解的信息,可以根据不同注解的和注解的属性来返回不同的class,
Object object = annotationAttributes.get("value");
boolean isTrue=object==null?false:Boolean.parseBoolean(object.toString());
if(isTrue){
Class beanClass = TestService2.class;
RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
String beanName = StringUtils.uncapitalize(beanClass.getSimpleName());
//在这里可以拿到所有注解的信息,可以根据不同注解来返回不同的class,从而达到开启不同功能的目的
//通过这种方式可以自定义beanName
registry.registerBeanDefinition(beanName, beanDefinition);
}
}
}
-
测试myTest2-spring-boot-starter
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.test</groupId>
<artifactId>myTest2-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.test</groupId>
<artifactId>myService</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
启动类测试:EnableMyTest(true)
@SpringBootApplication
@EnableMyTest(true)
public class StartApp3 {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(StartApp3.class, args);
try {
Object bean = applicationContext.getBean(TestService1.class);
System.out.println(bean);
}catch (Exception e){
System.out.println(e.getMessage());
}
try {
Object bean = applicationContext.getBean(TestService2.class);
System.out.println(bean);
}catch (Exception e){
System.out.println(e.getMessage());
}
}
}
com.test.service.TestService1@5d43661b
com.test.service.TestService2@12299890
启动类测试:EnableMyTest(false)
@SpringBootApplication
@EnableMyTest(false)
public class StartApp3 {
public static void main(String[] args) {
ConfigurableApplicationContext applicationContext = SpringApplication.run(StartApp3.class, args);
try {
Object bean = applicationContext.getBean(TestService1.class);
System.out.println(bean);
}catch (Exception e){
System.out.println(e.getMessage());
}
try {
Object bean = applicationContext.getBean(TestService2.class);
System.out.println(bean);
}catch (Exception e){
System.out.println(e.getMessage());
}
}
}
No qualifying bean of type 'com.test.service.TestService1' available
No qualifying bean of type 'com.test.service.TestService2' available