@Import、自定义注解、ClassPathBeanDefinitionScanner

@Import三种用法

1、引入普通类

2、引入ImportSelector的实现类

3、引入ImportBeanDefinitionRegister的实现类


以下以方式三为例:

配置类实现 ImportBeanDefinitionRegistrar 接口,可以自定义往容器中注册想注入的Bean。

该接口相比与 ImportSelector 接口的主要区别在于,ImportSelector接口是返回一个类,无法对这个类做操作, ImportBeanDefinitionRegistrar 是可以自己注入 BeanDefinition,添加属性等。

public class MyImportBeanRegistrar implements ImportBeanDefinitionRegistrar {/*** @param importingClassMetadata 当前类的注解信息* @param registry  注册类,registerBeanDefinition()可以注册bean*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {}
}

案例:自定义注解,将使用我们自定义注解并满足条件的类注入到spring容器中


自定义注解
参考博客:https://blog.csdn.net/dongzhanglong/article/details/120130237

@Target:注解的作用目标@Target(ElementType.TYPE)——接口、类、枚举、注解
@Target(ElementType.FIELD)——字段、枚举的常量
@Target(ElementType.METHOD)——方法
@Target(ElementType.PARAMETER)——方法参数
@Target(ElementType.CONSTRUCTOR) ——构造函数
@Target(ElementType.LOCAL_VARIABLE)——局部变量
@Target(ElementType.ANNOTATION_TYPE)——注解
@Target(ElementType.PACKAGE)——包,用于记录java文件的package信息

自定义包扫描注解
参考博客:https://blog.csdn.net/qq_16504067/article/details/120201048

// RetentionPolicy.RUNTIME 表示注解信息在运行时保留,在运行时可以通过反射获取注解信息,实现一些操作
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface MapperScan {/*** 扫描的包名*/String[] basePackages() default {};/*** 扫描的类名*/Class<?>[] basePackageClasses() default {};
}

自定义学生配置注解

//该注解可以应用于类、接口(包括注解类型)、枚举
@Target(ElementType.TYPE)
//被注解的元素包含在生成的Java文档中
@Documented
//该注解的生命周期,由JVM 加载,包含在类文件中,在运行时可以被获取到
@Retention(RetentionPolicy.RUNTIME)
public @interface StudentConfig {String name() default "luxifa";int age();
}

BeanDefinition子类实现介绍
参考博客:https://blog.csdn.net/c_c_f/article/details/119861188

对于bean定义只需要关注AbstractBeanDefinition和AnnotatedBeanDefinition就行。不要太注重与细节。

AbstractBeanDefinition:对BeanDefinition接口进行实现,并进行了扩展。
RootBeanDefinition、GenericBeanDefinition、ChildBeanDefinition是其子类。

AnnotatedBeanDefinition:注解类型的Bean定义。并扩展了注解相关的接口。

public interface AnnotatedBeanDefinition extends BeanDefinition {/*** 获取注解的元数据*/AnnotationMetadata getMetadata();/** 获取工厂方法的元数据*/@NullableMethodMetadata getFactoryMethodMetadata();
}

定义ImportBeanDefinitionRegister的实现类

参考博客:https://blog.csdn.net/qq_16504067/article/details/120201048

public class MyImportBean implements ImportBeanDefinitionRegistrar {/*** @param importingClassMetadata 当前类的注解信息* @param registry  注册类,registerBeanDefinition()可以注册bean*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {// 获取要扫描的包路径//聚合扫描的路径Set<String> basePackages = getBasePackages(importingClassMetadata);//获取扫描器ClassPathBeanDefinitionScanner scanner = getScanner(registry);//扫描并注册bdfor (String basePackage : basePackages) {//获取com.luxifa包下,使用StudentConfig注解的bean,该处值为com.luxifa.TestSet<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);for (BeanDefinition beanDefinition : candidateComponents) {//注册BD// ..可添加写过滤条件,比如StudentConfig注解中age小于35才让注入springbean中// 思路:判断bean定义是否为被注解的bean定义,是的话,转为被注解的bean定义,然后获取该被注解的bean定义中包含注解的所有信息,然后根据注解所在的类得到类加载器,根据类加载器得到我们的StudentConfig注解,然后判断StudentConfig注解上的age的值String beanClassName = beanDefinition.getBeanClassName();// 此处也可以自定义bean,然后注册registry.registerBeanDefinition(beanClassName, beanDefinition);}}private ClassPathScanningCandidateComponentProvider getScanner(BeanDefinitionRegistry registry) {//不使用默认的过滤器// true:默认TypeFilter生效,这种模式会查询出许多不符合你要求的class名// false:关闭默认TypeFilter// 参考博客:https://blog.csdn.net/qq_16504067/article/details/116642356ClassPathBeanDefinitionScannerscanner = new ClassPathBeanDefinitionScanner(registry, false);// 扫描我们自定义的注解scanner.addIncludeFilter(new AnnotationTypeFilter(StudentConfig.class));return scanner;}/*** 获取扫描组件的包路径*/protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {Map<String, Object> attributes = importingClassMetadata.getAnnotationAttributes(MapperScan.class.getCanonicalName());Set<String> basePackages = new HashSet<>();for (String pkg : (String[]) attributes.get("basePackages")) {if (StringUtils.hasText(pkg)) {basePackages.add(pkg);}}for (Class<?> clazz : (Class<?>[]) attributes.get("basePackageClasses")) {basePackages.add(ClassUtils.getPackageName(clazz));}if (basePackages.isEmpty()) {basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));}return basePackages;}}

自定义配置类中引入MyImportBeanRegistrar对象

package com.xx.example;
@Configuration
@Import(MyImportBean.class)
@MapperScan(basePackages={"com.luxifa"})
public class MyAutoConfiguration {}

将自定义的配置类MyAutoConfiguration 放到spring.factories文件中

#spring.factories 文件内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xx.example.MyAutoConfiguration

Demo服务中,Test.java类使用自定义StudentConfig注解
参考博客:https://blog.csdn.net/weixin_53233197/article/details/128402888

package com.luxifa;@StudentConfig(name="degula",age=25)
public class Test {}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/121600.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模型的保存加载、模型微调、GPU使用及Pytorch常见报错

序列化与反序列化 序列化就是说内存中的某一个对象保存到硬盘当中&#xff0c;以二进制序列的形式存储下来&#xff0c;这就是一个序列化的过程。 而反序列化&#xff0c;就是将硬盘中存储的二进制的数&#xff0c;反序列化到内存当中&#xff0c;得到一个相应的对象&#xff…

uniapp 处理 分页请求

我的需求是手机上一个动态滚动列表&#xff0c;下拉到底部时&#xff0c;触发分页数据请求 uniapp上处理分页解决方案 主要看你是如何写出滚动条的。我想到的目前有三种 &#xff08;1&#xff09;页面滚动&#xff1a;直接使用onReachBottom方法&#xff0c;可以监听到达底部…

文件读取漏洞复现(Metinfo 6.0.0)

文章目录 安装环境启动环境漏洞复现代码审计 安装环境 安装phpstudy&#xff0c;下载MetInfo 6.0.0版本软件&#xff0c;复制到phpstudy目录下的www目录中。 打开phpstudy&#xff0c;访问浏览器127.0.0.1/MetInfo6.0.0/install/index.php&#xff0c;打开Meinfo 6.0.0主页&a…

Vue+Element-ui实现表格本地导入

表格文件存储在前端 如图&#xff0c;表格文件template.xlsx存储在public下的static文件夹下 注意这里的路径容易报错 a链接下载文件失败的问题(未发现文件&#xff09; a.href ‘./static/template.xlsx’ 写的时候不能带public&#xff0c;直接这么写就可以 DownloadTemp…

leetcode每日一练-第53题-最大子数组和

一、思路 动态规划 二、解题方法 使用了两个变量 maxSum 和 currentSum 来分别记录全局的最大和和当前连续子数组的和。遍历数组时&#xff0c;我们不断更新 currentSum&#xff0c;并比较是否需要更新 maxSum。最后&#xff0c;maxSum 就是最大的连续子数组和。 三、code …

质量属性案例-架构真题(二十一)

试题一 某电子商务公司升级会员与促销管理系统&#xff0c;向用户提交个性化服务&#xff0c;提高用户粘性。在项目建立之初&#xff0c;公司领导人一致认为目标是提升会员管理方式的灵活性&#xff0c;由于当前用户规模不大&#xff0c;用户简单&#xff0c;系统方面不需要做…

【算法与数据结构】700、LeetCode二叉搜索树中的搜索

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;二叉搜索树的性质&#xff1a;左节点键值 < 中间节点键值 < 右节点键值。那么我们根据此性质&am…

seata1.4.2版本配置总结

文章目录 环境准备&#xff1a;seata-server配置registry.conf创建数据库表 nacos配置client配置seata_orderseata_storageseata_account 注意点 创建项目seata-order-service2001pom.xml文件application.yml 实体类CommonResultOrder DaoOrderDaoOrderMapper.xml config配置类…

文件上传漏洞全面渗透姿势

0x00 文件上传场景 (本文档只做技术交流) 文件上传的场景真的随处可见&#xff0c;不加防范小心&#xff0c;容易造成漏洞&#xff0c;造成信息泄露&#xff0c;甚至更为严重的灾难。 比如某博客网站评论编辑模块&#xff0c;右上角就有支持上传图片的功能&#xff0c;提交带…

指令系统(408)

一、拓展操作码指令格式 【2017 统考】某计算机按字节编址&#xff0c;指令字长固定且只有两种指令格式&#xff0c;其中三地址指令29条、二地址指令107条&#xff0c;每个地址字段6位&#xff0c;则指令字长至少应该是&#xff08; A&#xff09; A、24位 B、26位 …

Springboot + Sqlite实战(离线部署成功)

最近有个需求&#xff0c;是手机软件离线使用&#xff0c; 用的springboot mybatis-plus mysql&#xff0c;无法实现&#xff0c;于是考虑使用内嵌式轻量级的数据库SQLlite 引入依赖 <dependency><groupId>org.xerial</groupId><artifactId>sqlite-…

清理docker镜像方法

首先stop ps -a里的容器&#xff0c;然后rm容器&#xff0c;最后再rmi镜像 先停止容器 rm容器 docker rmi 镜像 删除后可以发现已经不存在

论文复现--VideoTo3dPoseAndBvh(视频转BVH和3D关键点开源项目)

分类&#xff1a;动作捕捉 github地址&#xff1a;https://github.com/HW140701/VideoTo3dPoseAndBvh 所需环境&#xff1a; Windows10&#xff0c;CUDA11.6&#xff0c;conda 4.13.0&#xff1b; 目录 环境搭建conda list配置内容演示生成文件说明 环境搭建 # 创建环境 conda…

uniapp 配置并使用 VueX

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 uni-app 内置了 VueX 1、创建需要的文件 右键点击 根目录【我的是 uni-shop】&#xff0c;然后新建 目录&a…

网络安全-IP地址信息收集

本文为作者学习文章&#xff0c;按作者习惯写成&#xff0c;如有错误或需要追加内容请留言&#xff08;不喜勿喷&#xff09; 本文为追加文章&#xff0c;后期慢慢追加 IP反查域名 http://stool.chinaz.com/same https://tools.ipip.net/ipdomain.php 如果渗透目标为虚拟主机…

【力扣每日一题】2023.9.4 序列化和反序列化二叉搜索树

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目给我们一棵搜索二叉树&#xff0c;要我们将这棵二叉树转变为字符串&#xff0c;同时我们需要根据字符串再变回二叉树&#xff0c;具体…

基于单片机的万年历温度无线传输控制系统系统

一、系统方案 本设计采用DS1302采集年月日时分秒&#xff0c;DS18B20采集温度值&#xff0c;按键设置温度报警上下限&#xff0c;实际测量温度低于下限或高于上限&#xff0c;蜂鸣器报警&#xff0c;同时将测量温度上传到蓝牙助手。 二、硬件设计 原理图如下&#xff1a; 三…

基于Matlab实现频谱分析(附上源码+数据集)

Matlab是一个功能强大的数值计算和科学计算软件&#xff0c;可以用于频谱分析。频谱分析是一种信号处理技术&#xff0c;用于将时域信号转换为频域信号&#xff0c;以便更好地理解信号的频率特性。本文将介绍使用Matlab实现频谱分析的方法。 文章目录 部分源码完整源码数据集下…

Mysql高阶语句(二)

一、设置别名&#xff08;alias ——>as&#xff09; 在 MySQL 查询时&#xff0c;当表的名字比较长或者表内某些字段比较长时&#xff0c;为了方便书写或者 多次使用相同的表&#xff0c;可以给字段列或表设置别名。使用的时候直接使用别名&#xff0c;简洁明了&#xff0…

【微服务部署】三、Jenkins+Maven插件Jib一键打包部署SpringBoot应用Docker镜像步骤详解

前面我们介绍了K8SDockerMaven插件打包部署SpringCloud微服务项目&#xff0c;在实际应用过程中&#xff0c;很多项目没有用到K8S和微服务&#xff0c;但是用到了Docker和SpringBoot&#xff0c;所以&#xff0c;我们这边介绍&#xff0c;如果使用Jenkinsjib-maven-plugin插件打…