背景
@Configuration 注解的类会被spring自动的扫描注入为Bean,如果想自己定义一个注解实现相同的功能如何来实现
ImportBeanDefinitionRegistrar
熟悉spring源码的同学应该知道,注册bean实际上就是注册beandefinition
这个类刚好有接口可以实现
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
registerBeanDefinitions(importingClassMetadata, registry);
}
1.定义注解
此注解在类上定义
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
public @interface Ma {
}
2.启动注解
spring启动类上注解
引入ImportBeanDefinitionRegistrar实现
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperAutoConfigureRegistrar.class)
public @interface MapperAutoCon {
}
3.实现接口
public class MapperAutoConfigureRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
private ResourceLoader resourceLoader;
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
MapperBeanDefinitionScanner scanner = new MapperBeanDefinitionScanner(registry, false);
scanner.setResourceLoader(resourceLoader);
scanner.registerFilters();
//这里增加对Ma注解类的扫描
scanner.addIncludeFilter(new AnnotationTypeFilter(Ma.class));
//测试直接写死,可改成要scan的目录
scanner.doScan("com.si");
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
4.扫描器
public class MapperBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {
public MapperBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
super(registry, useDefaultFilters);
}
protected void registerFilters() {
addIncludeFilter(new AnnotationTypeFilter(Ma.class));
}
@Override
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
return super.doScan(basePackages);
}
}
5.使用Bean
@Configuration
public class Us {
//这里引入@Ma注解的
@Autowired
UserMapper userMapper;
@Autowired
public void init(){
userMapper.say();
}
}
6.使用注解
@Ma
public class UserMapper {
public void say(){
System.out.println("hello ");
}
}
7.启动类
@SpringBootApplication
//启动类中引入这个注解
@MapperAutoCon
public class MapperAutoConfigureRegistrarTest {
public static void main(String[] args) {
SpringApplication.run(MapperAutoConfigureRegistrarTest.class,args);
}
}
总结
实现了自定义注解功能,这个注解可以用作jar在其它项目中使用,对于造轮子来说还是可以的