自定义注解
注解本身只是元数据,描述了数据的数据,描述的对象可以是类、方法、属性、参数或构造器等。而自定义注解的实现是借助了接口的能力,通常有两类实现方式:BeanPostProcessor 和 BeanFactoryPostProcessor。
BeanPostProcessor
作用范围在属性,在类的属性上打上自定义注解,可以扩展类的能力。实现方法如下:
定义自定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectSideCar {
}
完成 BeanPostProcessor 的实现
@Component
public class InjectSidecarAnnotationBeanPostProcessor implements BeanPostProcessor {
private Class<? extends Annotation> changeAnnotationType;
@Autowired
private SideCar sideCar;
public InjectSidecarAnnotationBeanPostProcessor() {
this.changeAnnotationType = InjectSideCar.class;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
ReflectionUtils.doWithFields(bean.getClass(), field -> {
ReflectionUtils.makeAccessible(field);
if (field.isAnnotationPresent(changeAnnotationType)) {
field.set(bean, sideCar);
}
});
return bean;
}
}
使用自定义注解
@Component
public class Demo {
@InjectSideCar
private SideCar sideCar;
public void doSomething() {
System.out.println(sideCar.doSomething());
}
}
在测试类中进行验证:
@SpringBootTest
class HdlsApplicationTests {
@Autowired
private Demo d;
@Test
public void testDemo() {
d.doSomething();
}
}
运行结果如下:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)
2020-04-21 00:39:06.014 WARN 37818 --- [ main] o.s.boot.StartupInfoLogger : InetAddress.getLocalHost().getHostName() took 5003 milliseconds to respond. Please verify your network configuration (macOS machines may need to add entries to /etc/hosts).
2020-04-21 00:39:11.020 INFO 37818 --- [ main] com.example.hdls.HdlsApplicationTests : Starting HdlsApplicationTests on hdls.local with PID 37818 (started by zhuweiwei in /Users/zhuweiwei/Java/hdls)
2020-04-21 00:39:11.021 INFO 37818 --- [ main] com.example.hdls.HdlsApplicationTests : No active profile set, falling back to default profiles: default
2020-04-21 00:39:11.299 INFO 37818 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'sideCar' of type [com.example.hdls.SideCar] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-21 00:39:11.352 INFO 37818 --- [ main] com.example.hdls.HdlsApplicationTests : Started HdlsApplicationTests in 15.497 seconds (JVM running for 16.32)
I am a sidecar
BeanFactoryPostProcessor
作用范围在类,在类上打上自定义注解,可以实现自动注入 bean。实现方法如下:
自定义注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomBean {
}
完成 BeanFactoryPostProcessor 的实现
@Component
public class CustomBeanDefinitionRegistryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner((BeanDefinitionRegistry) configurableListableBeanFactory);
scanner.addIncludeFilter(new AnnotationTypeFilter(CustomBean.class));
scanner.scan("com.example.hdls");
}
}
使用自定义注解
@CustomBean
public class Demo {
public void doSomething() {
System.out.println("I am a custom bean.");
}
}
在测试类中进行验证:
@SpringBootTest
class HdlsApplicationTests {
@Autowired
private Demo d;
@Test
void contextLoads() {
}
@Test
public void testDemo() {
d.doSomething();
}
}
运行结果如下:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.2.6.RELEASE)
2020-04-21 00:45:28.288 WARN 37852 --- [ main] o.s.boot.StartupInfoLogger : InetAddress.getLocalHost().getHostName() took 5001 milliseconds to respond. Please verify your network configuration (macOS machines may need to add entries to /etc/hosts).
2020-04-21 00:45:33.298 INFO 37852 --- [ main] com.example.hdls.HdlsApplicationTests : Starting HdlsApplicationTests on hdls.local with PID 37852 (started by zhuweiwei in /Users/zhuweiwei/Java/hdls)
2020-04-21 00:45:33.299 INFO 37852 --- [ main] com.example.hdls.HdlsApplicationTests : No active profile set, falling back to default profiles: default
2020-04-21 00:45:33.566 INFO 37852 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'sideCar' of type [com.example.hdls.SideCar] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2020-04-21 00:45:33.619 INFO 37852 --- [ main] com.example.hdls.HdlsApplicationTests : Started HdlsApplicationTests in 15.497 seconds (JVM running for 16.223)
I am a custom bean.