Spring注解开发之组件注册(二)
Spring注解开发之组件注册(一)
5.@Import 给容器导入一个组件
给容器中注册组件
一、包扫描 + 组件标注注解(@Controller/@Service/@Repository/@Component) [自己写的类]
二、@Bean [导入的第三包里面的组件]
三、@Import [快速给容器中导入组件] (@Import{Color.class,Red.class})
1.@Import(要导入到容器中的组件),容器中就会自动注册这个组件,id默认是组件全名

2. @ImportSelector: 返回需要导入组建的全类名数组
// 自定义逻辑,返回需要导入的组件
public class MyImportSelector implements ImportSelector {// 返回值就是要导入到容器中的组件的全类名// AnnotationMetadata:当前标注@Import注解类的所有信息@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.lv.pojo.Blue", "com.lv.pojo.Yellow"};// 返回的类注入容器}
}
3.使用ImportBeanDefinitionRegister 手动注册bean到容器中
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/*** AnnotationMetadata:当前类的注解信息* BeanDefinitionRegistry:注册类* 把所有需要添加到容器中的bean,调用BeanDefinitionRegistry.registerBeanDefinition手动注册*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {// 查询容器中是否存在red组件boolean red = registry.containsBeanDefinition("com.xjhqre.pojo.Red");if (red) {// 指定bean的定义信息(bean的类型,bean的scope)BeanDefinition beanDefinition = new RootBeanDefinition(Purple.class);// 第一个参数指定bean的idregistry.registerBeanDefinition("purple", beanDefinition);}}
}
四、使用Spring提供的FactoryBean (工厂Bean)
1.默认获取到的是工厂bean调用getObject创建的对象
2.要获取工厂Bean本身,我们需要给id前面加一个& 即 &colorFactoryBean
// 创建一个Spring定义的FactoryBean
public class ColorFactoryBean implements FactoryBean<Color> {// 返回一个Color对象,这个对象会添加到容器中@Overridepublic Color getObject() throws Exception {return new Color();}@Overridepublic Class<?> getObjectType() {return Color.class;}// 返回是否为单例,// true 单实例 在容器中保存一份// false,则每次创建时调用getObject()方法@Overridepublic boolean isSingleton() {return true;}
}

在配置类中导入这个组件!!!
@Test
public void test5() {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig4.class);String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();// 工厂bean获取的是调用getObject创建的对象Object colorFactoryBean = applicationContext.getBean("colorFactoryBean");System.out.println(colorFactoryBean.getClass());// 如果想要拿到colorFactoryBean对象,则需要在传入的id前加一个&标识Object colorFactoryBean2 = applicationContext.getBean("&colorFactoryBean");System.out.println(colorFactoryBean2.getClass());
}
6.Bean生命周期
即bean从创建 ----> 初始化 -----> 销毁的过程
容器管理bean的生命周期;
我们可以自定义初始化和销毁方法,容器在bean进行进行到当前生命周期可以自定义初始化和销毁方法
构造(对象创建)
- 单实例:在容器启动的时候创建对象
- 多实例:在每次获取的时候创建对象
初始化
- 对象完成创建,并赋值好后,调用初始化方法
销毁
-
单实例:在容器关闭的时候销毁
-
多实例:容器不会管理这个bean,所以不会调用销毁方法(初始化会在第一次使用这个对象时才会创建)

初始化和销毁方法:
- 通过@Bean注解指定init-method和destroy-method


-
实现InitializingBean和DisposableBean接口,重写里面的destroy和afterPropertiesSet方法
- 通过让bean实现
InitializingBean接口来定义初始化逻辑 - 通过让bean实现
DisposableBean接口来定义销毁逻辑 - 在
InitializingBean中有一个方法afterPropertiesSet,该方法在bean创建并赋值后调用
- 通过让bean实现
-
使用@PostConstruct和@PreDestroy注解
- @PostConstruct:在bean创建完成并且属性赋值完成后进行初始化
- @PreDestroy:在容器销毁bean之前执行
-
BeanPostProcessor:接口,bean后置处理器,在bean初始化前后进行一些处理
- postProcessBeforeInitialization:在初始化之前执行
- postProcessAfterInitialization:在初始化之后执行
BeanPostProcessor执行原理
1.执行populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
2.开始initializeBean初始化bean
1.先执行applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);,遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
2.然后执行invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
3.最后执行applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

7.@Value 属性赋值


8.自动装配
Spring利用依赖注入(DI)完成对IOC容器中各个组件的依赖关系赋值
-
@Autowired:自动注入
(1)默认优先按照类型去容器中去找对应的组件: applicationContext.getBean(BookDao.class);如果找到了则进行赋值;
(2)如果找到了多个相同类型的组件,再将属性的名称作为组件的id去容器中查找applicationContext.getBean(“bookDao”)
(3)@Qualifier(“bookDao”):使用 @Qualifier 指定需要装配的组件的id,而不是使用属性名
(4)自动装配默认一定要将属性赋值好,没有就会报错,可以使用@Autowired(required = false);来设置为非必须的
(5)可以利用@Primary:让Spring在进行自动装配的时候,默认使用首选的bean,也可以继续使用@Qualifier(“bookDao”)来明确指定需要装配的bean的名字 -
Spring还支持使用**@Resource(JSR250)**和@Inject(JSR330) [Java规范注解]
-
@Resource 可以和@Autowired一样自动装配功能,默认是按照组件名称进行装配的;没有能支持@primary功能没有支持@Autowired(required = false)
-
@Inject:需要导入java.inject的包,和@Autowired的功能一样
-

-
@Autowired:Spring定义的 @Resource和@Inject都是java规范的AutowiredAnnotationBeanPostProcessor:解析完成自动装配 以上注解都装配进去了
-
方法、构造器位置的自动装配
-
放在方法上,@Bean+方法参数:参数从容器中获取 ,默认不写@Autowired


-
标在构造器上只有一个有参构造器,这个有参构造器的@Autowired可以省略,其参数位置的组件还是可以自动从容器中获取 默认加在ioc容器中的组件,容器会调用无参构造器创建对象,再进行初始化赋值等操作

-
-
Aware注入Spring底层组件 原理
- Aware 接口,提供了类似回调函数的功能
- 自定义组件想要使用Spring 容器底层的一些组件(ApplicationContext,BeanFactory);自定义组件需要实现xxxAware接口;在创建对象的时候,会调用接口规定的方法注入相关组件
- 原理:通过对应的Processor进行处理的 ApplicationContextAware => ApplicationContextAwareProcessor 后置处理器,在创建完bean后,看见bean实现了相关Aware接口,将组件传进来
9.@Profile环境搭建
Spring我们提供的可以根据当前环境,动态的激活和切换一系列组建的功能
开发、生产、测试环境 数据源的不同
@Profile 指定组件在那个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这组件

我们需要在项目的src/main/resources目录下新建一个配置文件,例如dbconfig.properties,在其中写上数据库连接的相关信息,如下所示。
db.user=root
db.password=123456
db.driverClass=com.mysql.jdbc.Driver
import javax.sql.DataSource;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.StringValueResolver;import com.mchange.v2.c3p0.ComboPooledDataSource;/**** @author liayun**/
@PropertySource("classpath:/dbconfig.properties") // 加载外部的配置文件
@Configuration
public class MainConfigOfProfile implements EmbeddedValueResolverAware {@Value("${db.user}")private String user;private StringValueResolver valueResolver;private String dirverClass;@Bean("testDataSource")public DataSource dataSourceTest(@Value("${db.password}") String pwd) throws Exception {ComboPooledDataSource dataSource = new ComboPooledDataSource();dataSource.setUser(user);dataSource.setPassword(pwd);dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");dataSource.setDriverClass(dirverClass);return dataSource;}@Bean("devDataSource")public DataSource dataSourceDev(@Value("${db.password}") String pwd) throws Exception {ComboPooledDataSource dataSource = new ComboPooledDataSource();dataSource.setUser(user);dataSource.setPassword(pwd);dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm_crud");dataSource.setDriverClass(dirverClass);return dataSource;}@Bean("prodDataSource")public DataSource dataSourceProd(@Value("${db.password}") String pwd) throws Exception {ComboPooledDataSource dataSource = new ComboPooledDataSource();dataSource.setUser(user);dataSource.setPassword(pwd);dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/scw_0515");dataSource.setDriverClass(dirverClass);return dataSource;}// 继承EmbeddedValueResolverAware接口// 他的实现就是直接用${db.driverClass}获取配置文件的值@Overridepublic void setEmbeddedValueResolver(StringValueResolver resolver) {this.valueResolver = resolver;dirverClass = valueResolver.resolveStringValue("${db.driverClass}");}}
相关文章:
Spring注解开发之组件注册(二)
Spring注解开发之组件注册(一) 5.Import 给容器导入一个组件 给容器中注册组件 一、包扫描 组件标注注解(Controller/Service/Repository/Component) [自己写的类] 二、Bean [导入的第三包里面的组件] 三、Import [快速给容器中导入组件] (Import{…...
【web前端开发】CSS最常用的11种选择器
文章目录1.CSS介绍2.CSS的语言规则3.CSS的引入方式4.选择器标签选择器类选择器id选择器通配符选择器复合选择器后代选择器子代选择器并集选择器交集选择器伪类选择器hover伪类选择器active伪类选择器结构伪类选择器结语1.CSS介绍 CSS (Cascading Style Sheets,层叠样…...
微电影广告发展的痛点
微电影广告以不可阻挡之势进入大众生活中,企业利用微电影广告来进行企业形象塑造的例子比比皆是。于是乎,微电影广告在为企业塑造品牌形象方面上取得了可喜的效果,但也不可忽视,在这个发展过程中,微电影广告所面临的问…...
uniapp新手入门
前言: 这篇文章主要写的是uniapp的基础知识,可以让大家快速上手uniapp,同时避掉一些可能踩到的坑。 一. 什么是uniapp uniapp是由dcloud 公司开发的多端融合框架。uniapp的出现让我们的开发更为方便,一次开发,多端运行…...
linux segfault at 问题定位实践
问题:程序崩溃,打印为:app[13016]: segfault at 7fb668d29930 ip 00007fb668d3c23c sp 00007fb668e7de20 error 7 in mydefine.so[7fb668d3400011000]定位步骤:基础分析数据,大概了解反馈信息(根据chatGPT&…...
SpringCloud+SpringCloudAlibaba
架构的演进1.1单体架构将所有业务场景的表示层、业务逻辑层和数据访问层放在一个工程中,最终经过编译、打包,部署在一台服务器上。◆ 1.1.1单体架构的优点1)部署简单: 由于是完整的结构体,可以直接部署在一个服务器上即可。2&…...
华为OD机试 - 路灯照明(C 语言解题)【独家】
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 使用说明本期题目:路灯照明…...
Linux程序替换
Linux程序替换创建子进程的目的?程序替换如何实现程序替换?什么是程序替换?先见一见单进程版本的程序替换程序替换原理多进程版本的程序替换execl函数组简易版Shell创建子进程的目的? 目的:为了帮助父进程完成一些特定的任务&…...
@JsonFormat @DataTimeFormat 时间格式
省流:用JsonFormat即可有时候会看到入参dto里,在时间类型的变量上用DateTimeFormat,代码如下。public class XXXdto{DateTimeFormat(pattern "yyyy-MM-dd hh:mm:ss")private Date startDate; }这是为了入参传日期格式的值。即前端…...
带你玩转modbusTCP通信
modbus TCP Modbus TCP是一种基于TCP/IP协议的Modbus通信协议,它是Modbus协议的一种变体,用于在以太网上进行通信。Modbus TCP协议是一种开放的通信协议,它支持多种编程语言和操作系统,并且可以在不同的硬件和软件平台上进行通信…...
2021牛客OI赛前集训营-提高组(第三场)T2交替
2021牛客OI赛前集训营-提高组(第三场) 题目大意 一个长度为nnn的数组aaa,每秒都会变成一个长度为n−1n-1n−1的新数组a′aa′,其变化规则如下 如果当前数组aaa的大小nnn为偶数,则对于新数组a′aa′的每一个位置i(1≤…...
论文投稿指南——中文核心期刊推荐(金融)
【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…...
华为OD机试 - 不等式(C 语言解题)【独家】
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 使用说明本期题目:不等式题…...
90后老板用低代码整顿旅行社,创2000万年收,他是怎么做到的?(真实)
热爱旅游的92年成都小伙猴哥,大学毕业后开了一家旅行社,主要从事川藏、云南定制游服务。 从今年春节开始,国内各地旅游业开始复苏,向旅行社打电话咨询的人越来越多。 旅游的人多是好事,也是一种烦恼,因为…...
Apache Dubbo 存在反序列化漏洞(CVE-2023-23638)
漏洞描述 Apache Dubbo 是一款轻量级 Java RPC 框架 该项目受影响版本存在反序列化漏洞,由于Dubbo在序列化时检查不够全面,当攻击者可访问到dubbo服务时,可通过构造恶意请求绕过检查触发反序列化,执行恶意代码 漏洞名称Apache …...
【YOLO】YOLOv8训练自定义数据集(4种方式)
YOLOv8 出来一段时间了,继承了分类、检测、分割,本文主要实现自定义的数据集,使用 YOLOV8 进行检测模型的训练和使用 YOLOv8 此次将所有的配置参数全部解耦到配置文件 default.yaml,不再类似于 YOLOv5,一部分在配置文件…...
linux重置root用户密码
重置root密码 法一:rd.break 第 1 步:重启系统编辑内核参数 第 2 步:找到 linux 这行,在此行末尾空格后输入rd.break (End键也可直接进入行尾) 成功后显示页面为: 第 3 步:查看。…...
【DBC专题】-10-CAN DBC转换C语言代码Demo_接收Rx报文篇
案例背景(共15页精讲): 该篇博文将告诉您,CAN DBC转换C语言代码Demo,只需传递对应CAN信号关联参数,无需每个信号"左移"和"右移",并举例介绍:在CANoe/Canalyzer中CAPL中的应用ÿ…...
AtCoder292 E 思维
题意: 给定一副n(n≤3000)n(n\leq 3000)n(n≤3000)个顶点,mmm条有向边的图,可以在图中添加有向边,求添加的最少边数,使得这副图满足:如果顶点aaa到顶点bbb有边,顶点bbb到ccc右有边,…...
20230309英语学习
What Is Sleep Talking? We Look at the Science 为什么人睡觉会说梦话?来看看科学咋说 Nearly everyone has a story about people talking in their sleep.Though it tends to be more common in children, it can happen at any age:A 2010 study in the jour…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
