Spring 中 ClassPathBeanDefinitionScanner 包扫描器的应用

代码演示

先定义两个实体类,不用 @Component 修饰,但是最终需要被 Spring 管理,代码如下:

public class Student {
	
}

public class Teacher {
	
}

然后定义注解 @BeansScanner 模拟 @ComponentScan 注解功能,代码如下:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(BeansScannerRegistrar.class)
public @interface BeansScanner {
	String basePackage() default "";

	boolean on() default true;
}

这里通过 @Import 注解将 BeansScannerRegistrar 类导入进来,BeansScannerRegistrar 类如下所示:

public class BeansScannerRegistrar implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {

		// ClassPathBeanDefinitionScanner defaultScanner = new ClassPathBeanDefinitionScanner(registry);
		BeanPackageScanner scanner = new BeanPackageScanner(registry);

		Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(BeansScanner.class.getName());
		annotationAttributes.forEach((k,v)->{
			System.out.println("获取到 BeansScanner 注解元数据= key= " + k+",val="+v);
		});

		String basePackage = (String)annotationAttributes.get("basePackage");

		// 这里添加过滤条件,我们重写了过滤条件,默认扫描指定包下面全部 class 文件
		scanner.addIncludeFilter(((metadataReader, metadataReaderFactory) -> true));

		// defaultScanner.scan(basePackage);
		scanner.doScan(basePackage);
	}
}

最后编写测试类:

@BeansScanner(basePackage = "com.gwm.scan.beans")
public class TestBean {
	public static void main(String[] args) {
		ApplicationContext context = new AnnotationConfigApplicationContext(TestBean.class);

		Student student = context.getBean(Student.class);
		Teacher teacher = context.getBean(Teacher.class);
		System.out.println("student = " + student);
		System.out.println("teacher = " + teacher);

	}
}

测试结果:

获取到 BeansScanner 注解元数据= key= basePackage,val=com.gwm.scan.beans
获取到 BeansScanner 注解元数据= key= on,val=true
student = com.gwm.scan.beans.Student@131ef10
teacher = com.gwm.scan.beans.Teacher@55b0dcab

可以发现这里还是借助了 ClassPathBeanDefinitionScanner 包扫描器,只是添加的过滤条件我们重写了,我们这里定义成这个包下面所有的 class 文件都可以封装成 BeanDefinition,并且注册到 BeanFactory 容器中。

我们从写的条件在 Spring 的源码中这里会调用到,如下所示:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔道不误砍柴功

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值