ClassPathBeanDefinitionScanner 自定义注解扫描器
自定义注解
java
// 自定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyComponent {
String value() default "";
}
// 类上添加上面的自定义注解
@MyComponent
public class UserComponent {
}
在 BeanDefinitionRegistryPostProcessor 中使用扫描器扫描
扫描指定目录下所有添加了自定义的 @MyComponent 注解的类,并在后面的流程中为其创建 BeanDefinition 对象,最终初始化到 Spring 容器中。
ClassPathBeanDefinitionScanner 继承了 ClassPathScanningCandidateComponentProvider 类。
ClassPathBeanDefinitionScanner 应用还有 MyBatis 中的 ClassPathMapperScanner 继承了 ClassPathBeanDefinitionScanner。
ClassPathScanningCandidateComponentProvider 的应用还有 @ServletComponentScan 注解,扫描类中包含 @WebServlet, @WebFilter, @WebListener 注解。
java
package com.github.mengweijin.mybatisplus.demo.ClassPathBeanDefinitionScanner.bean;
import com.github.mengweijin.mybatisplus.demo.ClassPathBeanDefinitionScanner.MyComponent.MyComponent;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Component;
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//根据BeanDefinitionRegistry对象获创建注解扫描器(Spring源码实现也是通过new 的方式)
//ClassPathBeanDefinitionScanner类就是自定义注解的支撑
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
// 添加自定义注解到注册器中(可以添加多个实现了 TypeFilter 的过滤器)
scanner.addIncludeFilter(new AnnotationTypeFilter(MyComponent.class));
// 指定注解扫描器的包路径(字符串)
scanner.scan("com.github.mengweijin.mybatisplus.demo.ClassPathBeanDefinitionScanner.MyComponent");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
测试
java
package com.github.mengweijin.mybatisplus.demo.ClassPathBeanDefinitionScanner;
import com.github.mengweijin.mybatisplus.demo.ClassPathBeanDefinitionScanner.MyComponent.UserComponent;
import org.junit.jupiter.api.Assertions;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication(scanBasePackages = "com.github.mengweijin.mybatisplus.demo.ClassPathBeanDefinitionScanner.bean")
public class MyComponentTest {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(MyComponentTest.class, args);
UserComponent bean = context.getBean(UserComponent.class);
System.out.println(bean);
Assertions.assertNotNull(bean);
context.close();
}
}