【Spring面试】六、@Autowired、@Configuration、第三方Bean的配置

news2024/12/24 11:05:43

文章目录

  • Q1、如何让自动注入没有找到依赖Bean时不报错?
  • Q2、如何让自动注入找到多个依赖的Bean时不报错?
  • Q3、@Autowired注解有什么作用?
  • Q4、@Autowired和@Resource之间的区别
  • Q5、@Autowired注解自动装配的过程是怎样的?
  • Q6、@Configuration的作用及解析原理
  • Q7、@Bean的方法调用是怎么保证单例的?
  • Q8、要将一个第三方的类配成Bean有哪些方式?
  • Q9、为什么@ComponentScan不设置basePackage也会扫描?

Q1、如何让自动注入没有找到依赖Bean时不报错?

答案:

@Autowired(required = false)   //默认为true
private Role role;
...

Q2、如何让自动注入找到多个依赖的Bean时不报错?

error:expected single matching bean but found 2....

给优先使用的Bean加注解@Primary

@Primary
@Component
....

Q3、@Autowired注解有什么作用?

// 可以标注在构造器、方法、参数、字段、注解类型(做为元注解)上
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
// 运行时注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

	/**
	 * Declares whether the annotated dependency is required.
	 * 声明该注解标注的依赖是否需要一定存在于Spring容器中
	 * 				true为必须存在,如果不存在的话就抛出NoSuchBeanDefinitionException异常
	 *				false不要求必须存在,如果不存在也不抛出异常(一般不建议设置,可能会引发线上事故)
	 * <p>Defaults to {@code true}.
	 */
	boolean required() default true;

}

答案:

是Spring依赖注入(DI)的方式之一。特性:

  • 先按类型注入,即byType
  • 如果类型匹配到了多个,则按名字注入,byName
  • 因此,不用额外提供属性的get和set方法
  • 搭配@Qualifier和@Primary解决多个同类型的Bean的问题
//在DI的地方指定bean的名字
@Service
public class UserService {

    @Autowired
    @Qualifier("user1")
    private IUser user;
}

//在Bean定义的地方加一个优先主要的声明
@Primary
@Service
public class User1 implements IUser{
    @Override
    public void say() {
    }
}

在这里插入图片描述

在构造方法上用@Autowired

这种写法会报错:

public class TraceConfig {

	@Autowired
	private Info info;

    private final AppConfig appConfig;

    public TraceConfig(Info info) {
        this.appConfig = info;
    }

	//....
}

正确写法:

public class TraceConfig {

    private final AppConfig appConfig;

    @Autowired
    public TraceConfig(Info info) {
        this.appConfig = info;
    }

	//....
}

第一种写法报错的原因是加载的顺序问题,@Autowired写在变量上的注入,要等到变量所在类完全加载完才注入,因此变量appConfig的加载要早于Info这个Bean,给appConfig赋值时,还没有注入。最后,在构造器上加Autowired注解,实际上还是使用了Autowired装配方式,并非构造器装配。

//构造器注入
public Class CarFactory{

	private Tank tank;

	public CarFactory(Tank tank) {  //按构造函数形参的类型去装配,byType
		this.tank = tank;  //按构造函数来自动装配
	}
}

在这里插入图片描述

在普通方法上加Autowired注解

@Service
public class UserService {

    @Autowired
    public void init() {
       //逻辑
    }
}

spring会在项目启动的过程中,自动调用一次加了@Autowired注解的方法,我们可以在该方法做一些初始化的工作

在set方法上加Autowired注解

@Service
public class UserService {

    private UserDao user;

    @Autowired
    public void setUser(UserDao user) {
        this.user = user;
    }
}

@Autowired标注可以放在成员变量上,也可以放在成员变量的set方法上。前者,Spring会直接将UserDao类型的唯一一个bean赋值给userDao这个成员变量;后者,Spring会调用setUserDao方法来将UserDao类型的唯一一个bean装配到userDao这个属性。

@Autowired用在方法的参数上

//构造方法的参数
@Service
public class UserService {

    private IUser user;

    public UserService(@Autowired IUser user) {
        this.user = user;
        System.out.println("user:" + user);
    }
}

//普通方法的参数
@Service
public class UserService {

    public void test(@Autowired IUser user) {
       user.say();
    }
}

@Autowired注入一个同类型所有Bean的list

@Service
public class UserService {

    @Autowired
    private List<IUser> userList;
    //...

}

此时@Autowired会自动把相同类型的IUser对象收集到集合中。

Q4、@Autowired和@Resource之间的区别

答案:

  • @Autowired是Spring提供的,@Resource是JDK提供的,不与框架强绑定
  • @Autowired是先按类型匹配,匹配到多个则按名字;@Resource默认按照名字去匹配,没匹配到则按类型去匹配

Q5、@Autowired注解自动装配的过程是怎样的?

@Autowired是通过Bean的后置处理器进行解析的,在创建一个Spring上下文的时候在构造函数中进行注册AutowiredAnnotationBeanPostProcessor,然后在Bean的创建过程中进行解析:

  • 实例化后进行预解析,即解析@Autowired标注的属性、方法,比如把属性的类型、名称、所在的类等元数据缓存起来
  • 在属性注入这一步进行真正的解析,即拿到上面缓存的元数据,去IoC容器中查找并返回注入

在根据元数据去容器中查找时:

  • 只找到一个,则将这个Bean装配给@Autowired指定的属性
  • 找到不止一个,则根据名称来查找
  • 一个也没找到,则throw exception,除非required=false

在这里插入图片描述

Q6、@Configuration的作用及解析原理

答案:

  • @Confiruration注解是用来代替xml配置方式下的spring.xml文件的(<bean>)
  • 但没有@Configuration也可以配置@Bean
  • 加了@Configuration注解会为配置类创建cglib动态代理,保证了配置类的内部方法之间依赖调用时都从容器中获取bean

在这里插入图片描述

关于解析原理:

  • 在创建Spring上下文的时候会注册一个解析配置处理器ConfigurationClassPostProcessor(实现BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor)
  • 在调用invokeBeanFactoyPostProcessor,就会去调用ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry进行解析配置(解析配置类说白就是去解析各种注解(@Bean @Confiquration@lmport @Component… 就是注BeanDefinition)
  • ConfigurationClassPostProcessor.postProcessBeanFactory去创建cglib动态代理

Q7、@Bean的方法调用是怎么保证单例的?

//同一个问题:
@Configuration加与不加的区别是什么?

答案:

  • 如果希望@Bean的方法返回是对象是单例,需要在类上面加上@Configuration
  • Spring 底层会为@Configuration(会在invokeBeanFactoryPostProcessor 通过内置BeanFactoryPostProcessor)生成CGLIB动态代理
  • 当@Bean方法进行互调时,则会通过CGLIB进行增强,通过调用的方法名作为Bean的名称去IoC容器中获取,进而保证了@Bean方法的单例

在这里插入图片描述

Q8、要将一个第三方的类配成Bean有哪些方式?

既然是第三方的类,那你总不能去他们代码中加一个@Component的注解,所以:

答案:

第一种:使用@Bean

@Configuration
public class MainConfig{
	@Bean
	public DruidDataSource dataSource(){
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setUrl("xxxx");
		return dataSource;
	}
}

第二种:使用@Import,但使用这种方式是不能像上面的@Bean一样干预这个对象的创建过程的,因为Spring直接反射+new Instance

@Import(DruidDataSource.class)
@Configuration
public class MainConfig{

}

如果想操作Bean的创建,可以通过用@Import的另一种用法:

在这里插入图片描述

第三种:通过扩展接口BeanDefinitionRegistryPostProcessor(创建BeanDefinition的扩展接口都可以用来操作Bean的生产)

在这里插入图片描述

Q9、为什么@ComponentScan不设置basePackage也会扫描?

正常用法中,@ComponentScan设置扫描包的地址,然后Spring去扫描包下所有类中带@Component注解的类,并注册为BeanDefinition

答案:

因为Spring在解析@ComponentScan的时候,拿到basePackage,如果没有设置,则将你的类所在的包路径做为扫描包的路径。

在这里插入图片描述

涉及的Spring解析的源码:

在这里插入图片描述

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

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

相关文章

sql server事务隔离别 、 mysql 事务隔离级别、并发性问题

隔离级别和锁 SQL中 mysql 、Oracle 、sql server 等数据库 都是客户端和服务器架构的软件&#xff0c;对于同一个服务器来说&#xff0c;可以有若干个客户端与之连接&#xff0c;每个客户端与服务器连接上之后&#xff0c;就可以称为一个 【会话&#xff08;session&#xff0…

leaflet 加载地图-引入各种地图

leaflet 加载地图-引入各种地图 一、智图地图 1、Geoq.Normal.Gray &#xff08;或 Geoq.Normal.Map&#xff09;灰色 let gaoDeLayer L.tileLayer.chinaProvider(Geoq.Normal.Gray);gaoDeLayer.addTo(this.map);2、Geoq.Normal.Warm 黄色 let gaoDeLayer L.tileLayer.chin…

计算机竞赛 基于计算机视觉的身份证识别系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器视觉的身份证识别系统 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng-sen…

2023年数维杯数学建模A题河流-地下水系统水体污染研究求解全过程文档及程序

2023年数维杯数学建模 A题 河流-地下水系统水体污染研究 原题再现&#xff1a; 河流对地下水有着直接地影响&#xff0c;当河流补给地下水时&#xff0c;河流一旦被污染&#xff0c;容易导致地下水以及紧依河流分布的傍河水源地将受到不同程度的污染&#xff0c;这将严重影响…

安全可靠的文件传输服务助力完成更高效的医疗保健工作(上)

医疗保健工作是关乎人类健康和社会进步的重要领域&#xff0c;需要处理和传输大量医疗数据&#xff0c;如患者资料、医疗图像、化验单、电子病历、诊断建议等。这些数据不仅涉及患者的个人隐私和医疗安全&#xff0c;还关系到医院的运行效率和医疗水平。 因此&#xff0c;如何…

推荐5款同类型中独树一帜的软件

今天要给大家推荐的是5款软件&#xff0c;每个都是同类软件中的个中翘楚&#xff0c;请大家给我高调地使用起来&#xff0c;不用替我藏着掖着。 1.动画演示制作——Focusky ​ Focusky 是一款专业的动画演示制作软件&#xff0c;可以让你用简单直观的方式制作各种折线图、柱状…

智慧工地:让工地可视化、数字化、智能化

智慧工地平台功能包括&#xff1a;劳务管理、施工安全管理、视频监控管理、机械安全管理、危大工程监管、现场物料监管、绿色文明施工、安全隐患排查、施工综合管理、施工质量管理、设备管理、系统管理等模块。 一、项目开发环境 技术架构&#xff1a;微服务 开发语言&#…

win11怎么删除PIN码

现在有很多用户都将电脑更新升级成win11系统&#xff0c;一些小伙伴对新系统的某些操作不是很熟悉&#xff0c;近期就有一部分小伙伴想要知道win11系统如何删除PIN码&#xff0c;这里小编就给大家详细介绍一下win11删除PIN码的教程&#xff0c;有需要的小伙伴快来看一看吧。 w…

解决: 使用html2canvas和print-js打印组件时, 出现空白页

如图所示: 当我利用html2canvas转换成图片后, 然后使用print-js打印多张图片, 会出现空白页 使用html2canvas和print-js打印组件的文章可参考这个: Vue-使用html2canvas和print-js打印组件 解决: 因为是使用html2canvas转换成图片后才打印的, 而图片是行内块级元素, 会有间隙…

基于若依框架实现markdown在线编辑

基于若依框架实现markdown在线编辑 1. 下载mavon-editor npm install mavon-editor --save2. 打开main.js文件, 添加如下 // markdown组件 import { mavonEditor } from "mavon-editor"; import "mavon-editor/dist/css/index.css";// markdown组件 Vue…

【目标检测】YOLOv8:快速上手指南

YOLOv8概述 YOLOv8是YOLOv5团队在今年新推出的一代YOLO版本&#xff0c;与前几代版本相比&#xff0c;其性能和速度差距如下图所示&#xff1a; 和其它版本不同的是&#xff0c;该仓库并非起名为YOLOv8&#xff0c;而是公司名ultralytics&#xff0c;因为他们想将此版本作为一…

职场新人对测试用例的困惑

职场新人对测试用例的困惑无非有以下几点&#xff1a; 什么是测试用例&#xff0c;为什么要写测试用例&#xff1f; 不知道怎么写&#xff0c;写了也不知道写的是否完整。 一、什么是测试用例&#xff1f; 百科的释义&#xff1a; 测试用例是对一项特定的软件产品进行测试任…

探索多态的本质【C++】

文章目录 多态的构成条件虚函数虚函数的重写&#xff08;覆盖&#xff09; 虚函数重写的两个例外C11 override和final区分重载、覆盖(重写)、隐藏(重定义)抽象类接口继承和实现继承多态的原理虚函数表 动态绑定和静态绑定动态绑定静态绑定 单继承中的虚函数表多继承中的虚函数表…

基于51单片机实现W25Q64-FLASH读写

一、前言 STC89C52是一款8位单片机,具有强大的功能和灵活性,广泛应用于各种嵌入式系统中。W25Q64是一款容量为64Mb的串行闪存芯片,采用SPI接口进行通信。本项目利用STC89C52单片机实现对W25Q64闪存芯片的读写操作,实现数据的读取和存储。 在本项目中,通过模拟SPI(Seria…

本末科技再获融资,直驱机器人来到价值兑现前夕?

在去年10月完成近亿元A轮融资后&#xff0c;今年9月&#xff0c;本末科技又宣布完成数千万元A轮融资&#xff0c;由立湾资本领投&#xff0c;建元投资跟投&#xff0c;北拓资本担任公司长期独家财务顾问。 本末科技长期专注于机器人机械模组与动力供应领域。虽然我国自2013年起…

项目交付谈判的6大技巧

针对项目交付问题&#xff0c;在面对甲方时&#xff0c;项目经理如果采用“和事佬”的态度&#xff0c;在不违背合理性或不产生无法承担后果前提下&#xff0c;尽量满足甲方的要求&#xff0c;以便顺利交付。这样往往容易导致项目范围蔓延&#xff0c;如果控制不当&#xff0c;…

信息技术--案例分析

文章目录 1 信息核心素养2 具备核心素养的学生3 导入原则4 导入方法5 新课讲授方法6 教学方法选择的依据7 教学方法的实施原则8 教学方法的设计意图9 小结10 作业 前言&#xff1a; 分值&#xff1a;本章节的内容在信息技术笔试中占据45分的分值&#xff0c;分别是18题10分&am…

合同交付类项目如何高效管理?

美国项目管理协会(PMI)保罗格蕾斯曾说:“当今社会,一切都是项目,一切也将成为项目。”在“万事皆项目”的背景下&#xff0c;企业在运营过程中会产生大量的项目型业务活动&#xff0c;例如&#xff1a;举办市场活动、产品研发、进行企业内训、采购招标、工程建设等等。那么按照…

涉案资金30个小目标,山东烟台网警打掉特大网络黑客犯罪团伙!

在人们日常生活中&#xff0c;有时会遇到“政府网站无法正常访问”“ 购物网页离奇丢失”“ 棋牌网游无法登录”等问题&#xff0c;就很莫名其妙。 这些事情一而再、再而三地发生&#xff0c;你能想到其背后潜藏着“黑手”和神秘组织吗&#xff1f; 近日&#xff0c;山东烟台…

【LeetCode-中等题】59. 螺旋矩阵 II

文章目录 题目方法一&#xff1a;二维数组缩圈填数字方法二&#xff1a; 题目 方法一&#xff1a;二维数组缩圈填数字 定义四个边界条件&#xff0c;每转一圈&#xff0c;把数值填进去&#xff0c;然后缩小一圈&#xff0c;直到不满足条件位置 结束循环条件可以是&#xff1a; …