news 2026/6/19 15:15:05

使用Spring的BeanFactoryPostProcessor扩展点完成自定义注解扫描

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用Spring的BeanFactoryPostProcessor扩展点完成自定义注解扫描

使用Spring的BeanFactoryPostProcessor扩展点完成自定义注解扫描

一、概述

本次实验是上一次https://blog.csdn.net/2301_80749359/article/details/157651601?fromshare=blogdetail&sharetype=blogdetail&sharerId=157651601&sharerefer=PC&sharesource=2301_80749359&sharefrom=from_link的扩展,只是加了自定义注解较为方便。

二、具体步骤

2.1创建自定义注解

packagecom.itheima.ano;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;//设定在哪些类型上可以使用@Target(ElementType.TYPE)//设定作用的范围@Retention(RetentionPolicy.RUNTIME)public@interfaceMyComponent{// 配置value属性,以代表bean的名字Stringvalue();}

2.2引入扫描注解包的工具类

packagecom.itheima.utils;importcom.itheima.ano.MyComponent;importorg.springframework.core.io.Resource;importorg.springframework.core.io.support.PathMatchingResourcePatternResolver;importorg.springframework.core.io.support.ResourcePatternResolver;importorg.springframework.core.type.classreading.CachingMetadataReaderFactory;importorg.springframework.core.type.classreading.MetadataReader;importorg.springframework.core.type.classreading.MetadataReaderFactory;importorg.springframework.util.ClassUtils;importjava.lang.annotation.Annotation;importjava.util.HashMap;importjava.util.List;importjava.util.Map;publicclassBaseClassScanUtils{//设置资源规则privatestaticfinalStringRESOURCE_PATTERN="/**/*.class";publicstaticMap<String,Class>scanMyComponentAnnotation(StringbasePackage){//创建容器存储使用了指定注解的Bean字节码对象Map<String,Class>annotationClassMap=newHashMap<String,Class>();//spring工具类,可以获取指定路径下的全部类ResourcePatternResolverresourcePatternResolver=newPathMatchingResourcePatternResolver();try{Stringpattern=ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX+ClassUtils.convertClassNameToResourcePath(basePackage)+RESOURCE_PATTERN;Resource[]resources=resourcePatternResolver.getResources(pattern);//MetadataReader 的工厂类MetadataReaderFactoryrefractory=newCachingMetadataReaderFactory(resourcePatternResolver);for(Resourceresource:resources){//用于读取类信息MetadataReaderreader=refractory.getMetadataReader(resource);//扫描到的classStringclassname=reader.getClassMetadata().getClassName();Class<?>clazz=Class.forName(classname);//判断是否属于指定的注解类型if(clazz.isAnnotationPresent(MyComponent.class)){//获得注解对象MyComponentannotation=clazz.getAnnotation(MyComponent.class);//获得属value属性值StringbeanName=annotation.value();//判断是否为""if(beanName!=null&&!beanName.equals("")){//存储到Map中去annotationClassMap.put(beanName,clazz);continue;}//如果没有为"",那就把当前类的类名作为beanNameannotationClassMap.put(clazz.getSimpleName(),clazz);}}}catch(Exceptionexception){}returnannotationClassMap;}publicstaticvoidmain(String[]args){Map<String,Class>stringClassMap=scanMyComponentAnnotation("com.itheima");System.out.println(stringClassMap);}}

2.3利用工具类扫描包

利用工具类扫描包(包括该包及其子包下)中带有@MyComponent注释的类,然后遍历Map进行相关的操作(具体见代码注释)

packagecom.itheima.processor;importcom.itheima.utils.BaseClassScanUtils;importorg.springframework.beans.BeansException;importorg.springframework.beans.factory.config.BeanDefinition;importorg.springframework.beans.factory.config.ConfigurableListableBeanFactory;importorg.springframework.beans.factory.support.BeanDefinitionRegistry;importorg.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;importorg.springframework.beans.factory.support.RootBeanDefinition;importjava.util.Map;publicclassMyComponentBeanFactoryPostProcessorimplementsBeanDefinitionRegistryPostProcessor{@OverridepublicvoidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistrybeanDefinitionRegistry)throwsBeansException{//先是使用扫描的工具进行扫描Map<String,Class>myComponentAnnotationMap=BaseClassScanUtils.scanMyComponentAnnotation("com.itheima");// 然后是遍历这个map,得到bbeanDefinitionmyComponentAnnotationMap.forEach((beanName,beanClass)->{// 先是获取到全限制名(转为String类型的)StringclassName=beanClass.getName();// 然后是定义bbeanDefinitionBeanDefinitionbeanDefinition=newRootBeanDefinition();beanDefinition.setBeanClassName(className);// 再是进行注册,这就是放到单例池单中了beanDefinitionRegistry.registerBeanDefinition(beanName,beanDefinition);});}@OverridepublicvoidpostProcessBeanFactory(ConfigurableListableBeanFactoryconfigurableListableBeanFactory)throwsBeansException{}}

2.4测试:

packagecom.itheima.test;importcom.alibaba.druid.pool.DruidDataSource;importcom.itheima.beans.OthrerBean;importcom.itheima.beans.Xxxbean;importcom.itheima.dao.impl.UserDaoImpl;importcom.itheima.dao.personDao;importcom.itheima.service.UserService;importcom.mysql.jdbc.Connection;importorg.apache.ibatis.io.Resources;importorg.apache.ibatis.session.SqlSession;importorg.apache.ibatis.session.SqlSessionFactory;importorg.apache.ibatis.session.SqlSessionFactoryBuilder;importorg.springframework.beans.factory.config.BeanDefinition;importorg.springframework.beans.factory.support.DefaultListableBeanFactory;importorg.springframework.beans.factory.xml.XmlBeanDefinitionReader;importorg.springframework.context.ApplicationContext;importorg.springframework.context.support.ClassPathXmlApplicationContext;importjavax.xml.bind.annotation.XmlAccessOrder;importjava.io.IOException;importjava.io.InputStream;importjava.sql.DriverManager;publicclassBeanFactoryTest{publicstaticvoidmain(String[]args)throwsException{ApplicationContextapplicationContext=newClassPathXmlApplicationContext("applicationContext_beanfac.xml");OthrerBeanothrerBean=(OthrerBean)applicationContext.getBean("otherBean");System.out.println(othrerBean);}}

结果:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 21:51:47

【山海鲸实战案例】通过二维组件控制三维场景昼夜变化

在项目制作过程中&#xff0c;我们可能会需要手动控制三维场景的昼夜切换&#xff0c;此时通过按钮组件的交互设置就可以非常简单地达到目的&#xff0c;下面我们就来看一下具体该如何进行设置。 首先&#xff0c;创建一个三维场景。 添加两个“按钮”组件&#xff0c;分别命名…

作者头像 李华
网站建设 2026/6/13 11:15:59

原子层加工技术推动碳化硅量子光子电路发展

原子层加工技术助力碳化硅量子光子电路蓬勃发展 来自马克斯普朗克光科学研究所&#xff08;Max Planck Institute for the Science of Light&#xff09;与弗劳恩霍夫集成系统与元器件技术研究所&#xff08;Fraunhofer Institute for Integrated Systems and Device Technolo…

作者头像 李华
网站建设 2026/6/13 10:39:09

深圳跨境电商中的“亚马逊精品模式“详解

深圳跨境电商中的"亚马逊精品模式"详解 一、核心定义 亚马逊精品模式是跨境电商中一种"少而精"的运营策略&#xff0c;指卖家专注于少数高潜力产品&#xff08;通常成熟期仅需10-20款&#xff09;&#xff0c;通过深度选品、精细化运营和供应链优化&#x…

作者头像 李华
网站建设 2026/6/16 18:46:43

SAP ABAP代码实现常规数据批导(剪切板方式)

SAP中经常会需要开发很多批导的程序&#xff0c;一般会用Excel上传数据的方式&#xff0c;这种经常会出现excel的各种问题&#xff0c;处理起来也麻烦。所以本文介绍另外一种方式&#xff0c;全程不使用Excel下载或者上传&#xff0c;使用剪切板获取模板和上传数据。一、导出模…

作者头像 李华
网站建设 2026/6/15 18:04:29

ESP32-S2-MINI-2:高性能、高集成度的物联网Wi-Fi模组解析

ESP32-S2-MINI-2是一款紧凑的2.4 GHz Wi-Fi(802.11 b/g/n)模块&#xff0c;内置ESP32-S2 系列芯片&#xff08;版本v1.0&#xff09;&#xff0c;搭载Xtensa单核32位LX7微控制器。该模块通过芯片叠封技术集成4MB flash&#xff0c;并支持额外叠封2MB PSRAM&#xff0c;提供多达…

作者头像 李华
网站建设 2026/6/10 11:43:41

企业AI转型困境,AI应用架构师路线图来拯救

企业AI转型困境突围&#xff1a;AI应用架构师路线图指南 关键词&#xff1a;企业AI转型、AI应用架构师、转型困境、路线图、AI技术应用 摘要&#xff1a;本文旨在深入剖析企业AI转型过程中面临的诸多困境&#xff0c;并通过构建AI应用架构师路线图为企业提供有效解决方案。从阐…

作者头像 李华