spring注解驱动系列--自动装配

Spring利用依赖注入(DI),完成对IOC容器中中各个组件的依赖关系赋值;依赖注入是spring ioc的具体体现,主要是通过各种注解进行属性的自动注入。

一、@Autowired:自动注入

一、注解介绍

1、默认优先按照类型去容器中找对应的组件;
2、如果找到多个相同类型的组件,再将属性的名称作为组件的id去容器中查找
3、@Qualifier("bookDao"):使用@Qualifier指定需要装配的组件的id,而不是使用属性名
4、自动装配默认一定要将属性赋值好,没有就会报错;
      可以使用@Autowired(required=false);
5、@Primary:让Spring进行自动装配的时候,默认使用首选的bean;
    也可以继续使用@Qualifier指定需要装配的bean的名字
         BookService{
              @Autowired
              BookDao  bookDao;
         }

二、AutowiredAnnotationBeanPostProcessor

 @Autowired主要是通过AutowiredAnnotationBeanPostProcessor这个类实现的

三、使用地方 

1、[标注在方法位置]:@Bean+方法参数;参数从容器中获取;默认不写@Autowired效果是一样的;都能自动装配
2、[标在构造器上]:如果组件只有一个有参构造器,这个有参构造器的@Autowired可以省略,参数位置的组件还是可以自动从容器中获取
3、放在参数位置

/*** @Bean标注的方法创建对象的时候,方法参数的值从容器中获取* @param car* @return*/@Beanpublic Color color(Car car){Color color = new Color();color.setCar(car);return color;}

二、@Resource(JSR250)和@Inject(JSR330)

Spring还支持使用@Resource(JSR250)和@Inject(JSR330)[java规范的注解] 

一、@Resource:

可以和@Autowired一样实现自动装配功能;默认是按照组件名称进行装配的;
不支持@Primary功能也没有@Autowired(reqiured=false)这种功能; 

二、@Inject:

 需要导入javax.inject的包,和Autowired的功能一样。没有required=false的功能; 

注意:@Autowired:Spring定义的; @Resource、@Inject都是java规范 

三、自定义组件

一、自定义组件想要使用Spring容器底层的一些组件

自定义组件想要使用Spring容器底层的一些组件,例如:想要获取底层ApplicationContext(IOC)组件,BeanFactory等等。可以自定义实现xxxAware接口,在创建对象的时候,会调用接口规定的方法注入相关组件 ;把Spring底层一些组件注入到自定义的Bean中。一般xxxAware接口功能都是使用xxxProcessor实现;

例如:ApplicationContextAware==》ApplicationContextAwareProcessor;

 ApplicationContextAware接口只有一个方法

public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext var1) throws BeansException;

}

而ApplicationContextAwareProcessor是实现BeanPostProcessor接口里面的方法(后置处理器)

public interface BeanPostProcessor {@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}

然后ApplicationContextAwareProcessor会在对象初始化前调用postProcessBeforeInitialization将ApplicationContext设置进实现 ApplicationContextAware接口的对象的setApplicationContext方法中,然后我们想要使用的时候,只需要将ApplicationContext对象保存在当前对象中即可,具体栗子如下:

/**
实现对应的xxxAware,然后实现对应的方法,
例如:ApplicationContextAware,当red对象生成后,ApplicationContextAwareProcessor还在初始化
前将ApplicationContext 传入到setApplicationContext这个方法中,然后red方法会保存在当前属性中,
在red对象中,写对应的业务逻辑是如果需要获取容器中的对象可以通过ApplicationContext 进行获取。
**/
@Component
public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// TODO Auto-generated method stubSystem.out.println("传入的ioc:"+applicationContext);this.applicationContext = applicationContext;}@Overridepublic void setBeanName(String name) {// TODO Auto-generated method stubSystem.out.println("当前bean的名字:"+name);}@Overridepublic void setEmbeddedValueResolver(StringValueResolver resolver) {// TODO Auto-generated method stubString resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");System.out.println("解析的字符串:"+resolveStringValue);}}

 二、ApplicationContextAware接口实现原理,源码展示


class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ConfigurableApplicationContext applicationContext;private final StringValueResolver embeddedValueResolver;public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {this.applicationContext = applicationContext;this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());}@Nullablepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {AccessControlContext acc = null;// 判断red实现的是哪一个接口if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {acc = this.applicationContext.getBeanFactory().getAccessControlContext();}if (acc != null) {// 权限检查,如:判断能不能够访问对应的方法 AccessController.doPrivileged(() -> {this.invokeAwareInterfaces(bean);return null;}, acc);} else {// 主要是调用这个方法this.invokeAwareInterfaces(bean);}return bean;}/**主要是匹配对应实现的接口,例如:匹配到ApplicationContextAware,会调用setApplicationContext将applicationContext设置进实现接口的对象方法中**/private void invokeAwareInterfaces(Object bean) {if (bean instanceof Aware) {if (bean instanceof EnvironmentAware) {((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());}if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);}if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);}if (bean instanceof MessageSourceAware) {((MessageSourceAware)bean).setMessageSource(this.applicationContext);}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);}}}public Object postProcessAfterInitialization(Object bean, String beanName) {return bean;}
}

四、Profile

Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能。

@Profile:指定组件在哪个环境的情况下才能被注册到容器中,不指定,任何环境下都能注册这个组件

1、加了环境标识的bean,只有这个环境被激活的时候才能注册到容器中。默认是default环境

2、写在配置类上,只有是指定的环境的时候,整个配置类里面的所有配置才能开始生效

3、没有标注环境标识的bean在,任何环境下都是加载的;

栗子:

@Profile("prod")

@Profile("dev")

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

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

相关文章

高中数学:函数奇偶性

一、定义 偶函数:定义域关于原点对称,图像关于Y轴对称 f(x)f(-x) 奇函数:定义域关于原点对称,图像关于原点中心对称 f(x)f(-x)0 等价于 f(-x)-f(x) 二、函数奇偶性的四种情况 注意: 即奇又偶的函数,只有…

Linux入门到入土

Linxu Linux 简介 Linux 内核最初只是由芬兰人林纳斯托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的。 Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX(可移植操作系统接口&#xff09…

【复现】宏景HCM 任意文件读取漏洞_63

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一: 四.修复建议: 五. 搜索语法: 六.免责声明 一.概述 宏景HCM 将人才标签技术应用于员工招聘、人才选拔等环节,通过多维度的标签体系,形成不同专业序列的人才画…

CV | 医学影像上的图像分割模型调研【更新于20240304】

mamba相关的图像分割:VM-Unet,Manba-Unet,BRAU-Net,MDD-Unet,EGE-Unet,U-Mamba 2024.01.01_BRAU-Net Paper:BRAU-Net: U-Shaped Hybrid CNN-Transformer Network for Medical Image Segmentation https://arxiv.org/pdf/2401.00722.pdf 2024.01.09_U-Mamba Paper:U…

猴子吃桃问题(python版)

文章预览: 题目python解法一:运行结果 python解法二:运行结果 python解法三:运行结果 题目 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。 第二天早…

flurl升级之后没有FlurlNewtonsoftJsonSerializer

新建NewtonsoftJsonSerializer.cs /// <summary> /// ISerializer implementation based on Newtonsoft.Json. /// Default serializer used in calls to GetJsonAsync, PostJsonAsync, etc. /// </summary> public class NewtonsoftJsonSerializer : IJsonSerial…

Qt 简约美观的加载动画 第九季

这次和大家分享6个非常清爽的加载动画. &#x1f60a; 效果如下 &#x1f60a; 一共三个文件 , 可以直接编译运行的呢 //main.cpp #include "LoadingAnimWidget.h" #include <QApplication> #include <QGridLayout> int main(int argc, char *argv[]) …

【JAVA重要知识 | 第三篇】深入理解并暴打AQS原理、ReentrantLock锁

文章目录 3.深入理解AQS、ReentrantLock3.1AQS3.1.1AQS简介3.1.2核心结构&#xff08;1&#xff09;设计模型&#xff08;2&#xff09;组成部分&#xff08;3&#xff09;State关键字 3.1.3实现的两类队列&#xff08;1&#xff09;同步队列①CLH②Node③主要行为 img条件队列…

中霖教育:注册安全工程师考是科目有哪些?

注册安全工程师的类型是职业资格证书&#xff0c;需要满足报名条件才能参加考试&#xff0c;考试通过就能发放证书。报名时间一般在八月份&#xff0c;考试时间在十月底左右。 考试科目&#xff1a; 《安全生产法律法规》 《安全生产管理》 《安全生产技术基础》 《安全生…

golang实现openssl自签名双向认证

第一步&#xff1a;生成CA、服务端、客户端证书 1. 生成CA根证书 生成CA证书私钥 openssl genrsa -out ca.key 4096创建ca.conf 文件 [ req ] default_bits 4096 distinguished_name req_distinguished_name[ req_distinguished_name ] countryName …

怎么使用curl2py自动构造爬虫代码并进行网络爬虫

目录 一、了解curl2py 二、安装curl2py 三、使用curl2py生成爬虫代码 四、实际案例&#xff1a;爬取网页数据 五、总结与建议 在当今数据驱动的时代&#xff0c;网络爬虫成为了获取数据的重要工具。对于初学者来说&#xff0c;手动编写爬虫代码可能是一项挑战。幸运的是&a…

PyTorch-神经网络

神经网络&#xff0c;这也是深度学习的基石&#xff0c;所谓的深度学习&#xff0c;也可以理解为很深层的神经网络。说起这里&#xff0c;有一个小段子&#xff0c;神经网络曾经被打入了冷宫&#xff0c;因为SVM派的崛起&#xff0c;SVM不了解的同学可以去google一下&#xff0…

JavaScript 基础学习笔记(五):函数、作用域、匿名函数

目录 一、函数 1.1 声明和调用 1.2 形参和实参 1.3 返回值 二、作用域 2.1 全局作用域 2.2 局部作用域 三、匿名函数 3.1 函数表达式 3.2 立即执行函数 一、函数 理解函数的封装特性&#xff0c;掌握函数的语法规则 1.1 声明和调用 函数可以把具有相同或相似逻辑的代…

NLP_文本张量表示方法(代码示例)

目标 了解什么是文本张量表示及其作用.文本张量表示的几种方法及其实现. 1 文本张量表示 将一段文本使用张量进行表示&#xff0c;其中一般将词汇为表示成向量&#xff0c;称作词向量&#xff0c;再由各个词向量按顺序组成矩阵形成文本表示. ["人生", "该&q…

Linux 实现打印彩色进度条

文章目录 预备知识一、理解回车换行二、认识行缓冲1、代码一、二&#xff08;回车换行理解&#xff09;2、代码三、四&#xff08;sleep函数和ffush函数理解&#xff09; 三、简单倒计时1. 倒计时代码2、效果展示 四、进度条1、效果展示2、进度条代码makefileProcessBar.hProce…

tomcat 反向代理 自建博客 修改状态页 等

一 自建博客 随后&#xff0c;拷贝到webapps下面 并且做软连接 随后重定向 并且下载 cat >/etc/yum.repos.d/mysql.repo <<EOF [mysql57-community] nameMySQL 5.7 Community Server baseurlhttp://repo.mysql.com/yum/mysql-5.7-community/el/7/x86_64/ enabled1 g…

第十四届蓝桥杯大赛B组 JAVA 蜗牛 (递归剪枝)

题目描述&#xff1a; 这天&#xff0c;一只蜗牛来到了二维坐标系的原点。 在 x 轴上长有 n 根竹竿。它们平行于 y 轴&#xff0c;底部纵坐标为 0&#xff0c;横坐标分别为 x1, x2, …, xn。竹竿的高度均为无限高&#xff0c;宽度可忽略。蜗牛想要从原点走到第 n 个竹竿的底部也…

全域电商数据集成管理与采集|API接口的采集与管理

如今&#xff0c;全渠道零售已是大势所趋。企业电商经营的一大现状就是数据分散各处&#xff0c;比如有来自电商平台私域数据、品牌一方数据、公开的第三方行业数据与电商平台C端页面数据等等。如何集成全域数据日益成为企业数字化基建的难题。 当前电商数据集成的主流方案为人…

【基于Matlab GUI的语音降噪系统设计】

客户不要了&#xff0c;挂网上吧&#xff0c;有需要自行下载~ 赚点辛苦费 ** 功能实现: ** 1、导入音频文件/录入音频&#xff0c;能实现播放功能。 2、对导入/录入的音频信号进行时域和频域分析&#xff0c;并制图。 3、可在导入/录入的音频信号上加入噪声&#xff0c;并能够播…

Apache JMeter 5.6.3 安装

源码下载 curl -O https://dlcdn.apache.org//jmeter/source/apache-jmeter-5.6.3_src.zipJMeter 下载 curl -O https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.6.3.zipjmeter.properties 里 设置中文 windows系统上解压&#xff0c;双击jmeter.bat 启动 执行参…