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.rhkb.cn/news/268401.html

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

相关文章

NoSQL--1.虚拟机网络配置

目录 1.初识NoSQL 1.1 NoSQL之虚拟机网络配置 1.1.1 首先,导入预先配置好的NoSQL版本到VMware Workstation中 1.1.2 开启虚拟机操作: 1.1.2.1 点击开启虚拟机: 1.1.2.2 默认选择回车CentOS Linux(3.10.0-1127.e17.x86_64) 7 …

kafka同步副本集及关键参数

上篇文章讲了副本机制是什么,一文读懂kafka内部怎么运行的-CSDN博客 这里深挖下同步副本集及里面的关键参数。副本会去leader副本拉去数据追加到自己日志中。 我们知道kafka副本的作用是提高系统的高可用。当leader副本挂了时,会从候选副本集中选者一个当…

《Spring Security 简易速速上手小册》第4章 授权与角色管理(2024 最新版)

文章目录 4.1 理解授权4.1.1 基础知识详解授权的核心授权策略方法级安全动态权限检查 4.1.2 主要案例:基于角色的页面访问控制案例 Demo 4.1.3 拓展案例 1:自定义投票策略案例 Demo测试自定义投票策略 4.1.4 拓展案例 2:使用方法级安全进行细…

贪吃蛇(C语言)步骤讲解

一:文章大概 使用C语言在windows环境的控制台中模拟实现经典小游戏 实现基本功能: 1.贪吃蛇地图绘制 2.蛇吃食物的功能(上,下,左,右方向控制蛇的动作) 3.蛇撞墙死亡 4.计算得分 5.蛇身加…

冒泡排序(C语言详解)

原理:从左到右一次比较,如果左侧数字比右侧数字大(小),则两数交换,否则比较下一 组数字,每一次大循环比较可以将乱序的最右侧数字改为最大(最小)&#xff0c…

低代码中的可视化表单:效率与灵活兼备的设计工具

近年来,随着数字化转型的加速推进,企业对于高效率、灵活性和可定制性的软件开发需求不断增长。传统的软件开发过程通常需要耗费大量的时间和资源,而低代码开发平台的出现为企业提供了一种更加快速和灵活的解决方案。在低代码开发平台中&#…

docker版本 jenkins配置gitlab自动部署

前端项目 Build steps pwd npm config set registry https://registry.npm.taobao.org npm -v node -v #npm install npm run build:prod tar -czvf QASystem.tar.gz distpwd cd /data/zhouxy37/vue_deploy tar -zxvf QASystem.tar.gz sudo mv dist QASystem cp -r QASyste…

(已解决)emoji及其特殊符号在vue中的使用

问题叙述 使用问题&#xff1a;在表情库中点击后无法展示对应的emoji表情&#xff0c;仅仅显示Unicode代码编号&#xff0c;按照vue eslint规则更改添加分号后&#xff0c;没有报错但是依旧无法正确渲染。 问题源码&#xff1a; <template><div><!-- 被点击的…

electron nsis 安装包 window下任务栏无法正常固定与取消固定 Pin to taskbar

问题 win10系统下&#xff0c;程序任务栏在固定后取消固定&#xff0c;展示的程序内容异常。 排查 1.通过论坛查询&#xff0c;应该是与app的api setAppUserModelId 相关 https://github.com/electron/electron/issues/3303 2.electron-builder脚本 electron-builder…

Chrome插件 | WEB 网页数据采集和爬虫程序

无边无形的互联网遍地是数据&#xff0c;品类丰富、格式繁多&#xff0c;包罗万象。数据采集&#xff0c;或说抓取&#xff0c;就是把分散各处的内容&#xff0c;通过各种方式汇聚一堂&#xff0c;是个有讲究要思考的体力活。君子爱数&#xff0c;取之有道&#xff0c;得注意遵…

Network LSA 结构简述

Network LSA主要用于描述一个区域内的网络拓扑结构&#xff0c;包括网络中的路由器和连接到这些路由器的网络。它记录了每个路由器的邻居关系、连接状态以及连接的度量值&#xff08;如带宽、延迟等&#xff09;&#xff0c;以便计算最短路径和构建路由表。display ospf lsdb n…

ASUS华硕天选5笔记本电脑FX607JV原装出厂Win11系统下载

ASUS TUF Gaming F16 FX607JV天选五原厂Windows11系统 适用型号&#xff1a; FX607JU、FX607JI、FX607JV、 FX607JIR、FX607JVR、FX607JUR 下载链接&#xff1a;https://pan.baidu.com/s/1l963wqxT0q1Idr98ACzynQ?pwd0d46 提取码&#xff1a;0d46 原厂系统自带所有驱动、…

【JS 算法题: 将 json 转换为字符串】

题目简介 其实就是手撕 JSON.stringfy()。 算法实现 输入 原则上来说&#xff0c;输入的是一个 json 对象。但需要考虑到异常情况&#xff0c;即输入了其它类型的数据&#xff0c;比如&#xff1a;12, true, ‘abc’, [‘red’, ‘green’], null, undefined 等。 输出 …

关于脉冲负载应用中电阻器,您需要了解的 11 件事?

不幸的是&#xff0c;电阻器在脉冲负载下可能会失效。当脉冲功率耗散到器件的电阻元件时&#xff0c;它会产生热量并增加电阻器的温度。过热会损坏电阻元件&#xff0c;导致电阻变化甚至设备开路。为了避免在设计中出现这种情况&#xff0c;以下是您在选择元件时应了解的有关电…

基于springboot的宠物咖啡馆平台的设计与实现论文

基于Spring Boot的宠物咖啡馆平台的设计与实现 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了基于Spring Boot的宠物咖啡馆平台的设计与实现的开发全过程。通过分析基于Spring Boot的宠物咖啡馆平台的设计与…

【大厂AI课学习笔记NO.65】机器学习框架和深度学习框架

笔记思维脑图已上传&#xff0c;访问我的主页可下载。 https://download.csdn.net/download/giszz/88868909 广义上&#xff0c;机器学习框架包含了深度学习框架。 本质上&#xff0c;机器学习框架涵盖分类、回归、聚类、异常检测和数据准备等各种学习方法。 深度学习框架涵…

[Vulnhub]靶场 Red

kali:192.168.56.104 主机发现 arp-scan -l # arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:d2:e0:49, IPv4: 192.168.56.104 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192.168.56.1 …

C++ 设计模式

文章目录 类图泛化实现关联聚合组合依赖总结 类内部的三种权限&#xff08;公有、保护、私有&#xff09;类的三种继承方式描述与图总结 面向对象七大原则单一职责原则&#xff08;Single Responsibility Principle&#xff09;里氏替换原则&#xff08;Liskov Substitution Pr…

笔记本hp6930p安装Android-x86补记

在上一篇日记中&#xff08;笔记本hp6930p安装Android-x86避坑日记-CSDN博客&#xff09;提到hp6930p安装Android-x86-9.0&#xff0c;无法正常启动&#xff0c;本文对此再做尝试&#xff0c;原因是&#xff1a;Android-x86-9.0不支持无线网卡&#xff0c;需要在BIOS中关闭WLAN…