自定义spring boot Enable注解
定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(TestServiceRegistrar.class)
public @interface EnableTestService {
String[] value() default {};
}
注意注解上的@Import, 可以直接导入一个类,或者是 实现ImportSelector接口或
ImportBeanDefinitionRegistrar接口。
2、此处以实现ImportBeanDefinitionRegistra为例
public class TestServiceRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment=environment;
}
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
//获取注解上的属性
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
metadata.getAnnotationAttributes(EnableTestService.class.getName(), true));
String[] attrs= (String[]) attributes.get("value");
System.out.println(attrs==null || attrs.length ==0? "is empty":attrs[0]);
//获取配置文件中的属性
String appName=this.environment.getProperty("test.hello.app-name");
BeanDefinition beanDefinition=new GenericBeanDefinition();
beanDefinition.setBeanClassName(TestService.class.getName());
MutablePropertyValues values = beanDefinition.getPropertyValues();
values.addPropertyValue("appName", appName);
registry.registerBeanDefinition(TestService.class.getSimpleName(),beanDefinition);
}
@EnableTestService(value = "hello")
@SpringBootApplication
public class TestApplication{
public static void main(String[] args) {
ApplicationContext applicationContext=SpringApplication.run(TestApplication.class, args);
TestService testService=applicationContext.getBean(TestService.class);
System.out.println("编码后的appName:"+testService.getEncodedAppName());
}
}
执行结果
hello
编码后的appName:bWpoVGVzdA==
也可以通过实现ImportSelector接口
public String[] selectImports(AnnotationMetadata metadata) {
return new String[]{TestService.class.getName()};
}
ImportSelector使用简单,返回对应的类名就行,但个人感觉灵活性不够,比如文中的读取配置文件的属性注入,用ImportSelector似乎无法实现。