Spring常用注解——@Autowired自动装配的作用和原理
创始人
2024-03-31 20:01:38
0

一. 认识·@Autowired

当我们在Spring框架中配置Bean时,常见的有三种办法:①使用xml ②使用注解 ③使用javeconfig。由于第一种方法需要在application.xml配置文件中使用大量标签来进行注入,就衍生了注解,我们只要使用@Autowired对成员变量、方法和构造函数进行标注,就可以来完成自动装配的工作, 通过 @Autowired的使用还可以消除 set ,get方法,大大减少了代码量。

eg:[使用xml配置文件注入Bean]

[使用@Autowired注解注入Bean]

  @Autowiredpublic IAccountDao dao;
    @Autowiredpublic IAccountService service;

二. 用法·@Autowired

 @Autowired
    替换:autowire属性,自动装配(默认按照类型装配,通过set方法,且方法可以省略)
    位置:修饰属性,set方法
    语法:@Autowired (默认为true)

@Autowired(required=false):表示忽略当前要注入的bean,如果有直接注入,没有跳过,不会报错。

 @Autowired(required="true"):表示注入的时候,该bean必须存在,否则就会注入失败。
    注意:1.如果容器中没有一个可以与之匹配且required属性为true则会报异常 NoSuchBeanDefinitionException
         2.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配
         3.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配,如果名称也没有匹配,则报异常
            NoUniqueBeanDefinitionException

        4.@Autowired是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier使用;

三.原理

看看源码:@Autowired 位于 org.springframework.beans.factory.annotation.Autowired包下,其实现原理就是调用了AutowiredAnnotationBeanPostProcessor类下的postProcessProperties()方法。

1.AutowiredAnnotationBeanPostProcessor是BeanPostProcesser的一个实现类它的主要功能就是对带注解的方法,set方法,和任意配置方法进行自动注入,这些注入的成员是通过注解来实现自动装配的。

在AutowiredAnnotationBeanPostProcessor类的构造方法中,我们可以看到,这些注解包括Spring的@Autowired和@Value注解,还支持JSR-330的@Inject注解(功能基本类似),这些注解都是基于AutowiredAnnotationBeanPostProcessor实现的。

 public AutowiredAnnotationBeanPostProcessor() {this.autowiredAnnotationTypes.add(Autowired.class);this.autowiredAnnotationTypes.add(Value.class);try {this.autowiredAnnotationTypes.add(ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));this.logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");} catch (ClassNotFoundException var2) {}}

 (Bean的生命周期:实例化,属性赋值,初始化,操作使用,销毁)

AutowiredAnnotationBeanPostProcessor方法的调用,完成了扫描并处理自动注入的构造方法,之后会返回来doCreateBean方法中,所以其调用逻辑主要集中在doCreateBean()方法中,调用applyMergedBeanDefinitionPostProcessors方法,完成扫描并且注入属性和方法。

doCreateBean()主要分为三个部分,第一个部分是在实例化 Bean 的时候在 createBeanInstance 方法中会调用 AutowiredAnnotationBeanPostProcessor 中的方法来获取需要自动注入的构造方法,第二部分是调用 AutowiredAnnotationBeanPostProcessor 的方法来完成对所有需要自动注入的属性和方法的解析和缓存,最后一部分就是在 populatedBean 方法中调用到 AutowiredAnnotationBeanPostProcessor 中的方法来完成需要自动注入属性的注入工作。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);}// 1.处理自动注入构造方法if (instanceWrapper == null) {instanceWrapper = this.createBeanInstance(beanName, mbd, args);}Object bean = instanceWrapper.getWrappedInstance();Class beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}synchronized(mbd.postProcessingLock) {if (!mbd.postProcessed) {try {// 2.扫描注解并注入this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);} catch (Throwable var17) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);}mbd.postProcessed = true;}}
......private  T populateBean(ResultSet rs, T bean, PropertyDescriptor[] props, int[] columnToProperty) throws SQLException {for(int i = 1; i < columnToProperty.length; ++i) {if (columnToProperty[i] != -1) {PropertyDescriptor prop = props[columnToProperty[i]];Class propType = prop.getPropertyType();Object value = null;if (propType != null) {value = this.processColumn(rs, i, propType);if (value == null && propType.isPrimitive()) {value = primitiveDefaults.get(propType);}}// 存入Beanthis.callSetter(bean, prop, value);}}return bean;}

 

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...