Spring的@Component注解怎么使用
本篇内容介绍了“Spring的@Component注解怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
创新互联建站长期为上千家客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为苍梧企业提供专业的成都网站制作、成都网站设计,苍梧网站改版等技术服务。拥有十载丰富建站经验和众多成功案例,为您定制开发。
1. 前言
实现一个类似@Controller
的注解(或者继承某个统一接口)来完成比如定时任务的统一注入或者Websocket处理器的统一注入等这种将某种共性的Bean动态注入。
// 模仿 Controller @XBean(description = "ETL JOB") public class JobShedule { @Caller(cron = "* * 0/5 * * ?") public void exec(){ // job } }
以上伪代码就是一个模仿Controller的定时任务Bean。
2. 设计思路
详细的开发设计思路我已经总结好了,各位同学只要按部就班就可以实现这个功能了。
2.1 定义扫描注解
定义一个类似@MappScan
的进行导入自定义ImportBeanDefinitionRegistrar
,并指定扫描包范围。
@Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @Import(XBeanDefinitionRegistrar.class) public @interface XBeanScan { String[] basePackages(); }
我们自定义了一个扫描注解@XBeanScan
。它有两个作用:
通过
basePackages
指定扫描包的范围。导入我们自定义
ImportBeanDefinitionRegistrar
的实现XBeanDefinitionRegistrar
。
2.2 定义目标Bean的通用标记
通常我们可以选择一个标识接口,所有其实现类都会注入Spring IoC;或者用更加方便的注解,所有被该注解标记的类都将注入Spring IoC。这里我们使用更加灵活方便的注解,实现了一个@XBean
标记注解:
@Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface XBean { String description() default ""; }
2.3 实现扫描器
Spring框架为我们提供了扫描器来注册被标记的Bean,它就是上节提到的ClassPathBeanDefinitionScanner
,我们继承它进行稍加改造:
public class XBeanDefinitionScanner extends ClassPathBeanDefinitionScanner { public XBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) { super(registry, useDefaultFilters); super.addIncludeFilter(new AnnotationTypeFilter(XBean.class)); } }
这里我们不使用默认的过滤器,我们指定了扫描器扫描的目标为被@XBean
标记的那些Bean。
2.4 实现 Bean 注册机
重头戏来了,我们需要将2.1到2.3定义的这些组件在ImportBeanDefinitionRegistrar
的实现中组装起来。
/** * The type X bean definition registrar. * * @author felord.cn * @since 2020 /9/18 22:59 */ public class XBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware { private ResourceLoader resourceLoader; @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 不使用默认过滤器 XBeanDefinitionScanner xBeanDefinitionScanner = new XBeanDefinitionScanner(registry, false); xBeanDefinitionScanner.setResourceLoader(resourceLoader); // 扫描XBeanScan注解指定的包 xBeanDefinitionScanner.scan(getBasePackagesToScan(importingClassMetadata)); } @Override public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } /** * 获取{@link XBeanScan}中声明的扫描包路径 * @param metadata the meta * @return 包路径数组 */ private String[] getBasePackagesToScan(AnnotationMetadata metadata) { String name = XBeanScan.class.getName(); AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true)); Assert.notNull(attributes, () -> "No auto-configuration attributes found. Is " + metadata.getClassName() + " annotated with " + ClassUtils.getShortName(name) + "?"); return attributes.getStringArray("basePackages"); } }
从注解元数据importingClassMetadata
解析我们需要的扫描路径basePackages
等元数据,然后让扫描器在该路径扫描即可。
2.5 使用
在具有@Configuration
标记的类或者Spring Boot的Main
类上使用@XBeanScan
即可,是不是非常简单!
其实
@ComponentScan
提供类似的功能。
“Spring的@Component注解怎么使用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!
本文题目:Spring的@Component注解怎么使用
网页网址:http://ybzwz.com/article/jssdgj.html