详解Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理

一、spring依赖注入使用方式

  • @Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注入方式为通过类型查找bean,即byType的,如果存在多个同一类型的bean,则使用@Qualifier来指定注入哪个beanName的bean。
  • 与JDK的@Resource的区别:@Resource是基于bean的名字,即beanName,来从spring的IOC容器查找bean注入的,而@Autowried是基于类型byType来查找bean注入的。
  • 与JDK的@Inject的区别:@Inject也是基于类型来查找bean注入的,如果需要指定名称beanName,则可以结合使用@Named注解,而@Autowired是结合@Qualifier注解来指定名称beanName。

二、spring依赖注入注解的实现原理

注解处理器

  • 在spring框架内部实现当中,注解实现注入主要是通过bean后置处理器BeanPostProcessor接口的实现类来生效的。BeanPostProcessor后置处理器是在spring容器启动时,创建bean对象实例后,马上执行的,对bean对象实例进行加工处理。
  • @Autowired是通过BeanPostProcessor接口的实现类AutowiredAnnotationBeanPostProcessor来实现对bean对象对其他bean对象的依赖注入的;
  • @Resource和@Inject是通过BeanPostProcessor接口的实现类CommonAnnotationBeanPostProcessor来实现的,其中如名字所述,即公共注解CommonAnotation,CommonAnnotationBeanPostProcessor是spring中统一处理JDK中定义的注解的一个BeanPostProcessor。该类会处理的注解还包括@PostConstruct,@PreDestroy等。

注解处理器的激活条件

  • AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor添加到spring容器的BeanPostProcessor的条件,即激活这些处理器的条件如下:

1.基于xml的spring配置

  • 在对应的spring容器的配置xml文件中,如applicationContext.xml,添加<context:annotation-config />和<context:component-scan />,或者只使用<context:component-scan />。
  • 两者的区别是<context:annotation-config />只查找并激活已经存在的bean,如通过xml文件的bean标签生成加载到spring容器的,而不会去扫描如@Controller等注解的bean,查找到之后进行注入;而<context:component-scan />除了具有<context:annotation-config />的功能之外,还会去加载通过basePackages属性指定的包下面的,默认为扫描@Controller,@Service,@Component,@Repository注解的类。不指定basePackages则是类路径下面,或者如果使用注解@ComponentScan方式,则是当前类所在包及其子包下面。

2.基于配置类的spring配置

  • 如果是基于配置类而不是基于applicationContext.xml来对spring进行配置,如SpringBoot,则在内部使用的IOC容器实现为AnnotationConfigApplicationContext或者其派生类,在AnnotationConfigApplicationContext内部会自动创建和激活以上的BeanPostProcessor。
  • 如果同时存在基于xml的配置和配置类的配置,而在注入时间方面,基于注解的注入先于基于XML的注入,所以基于XML的注入会覆盖基于注解的注入。

总结

  • @Autowired是Spring自带的,@Inject和@Resource都是JDK提供的,其中@Inject是JSR330规范实现的,@Resource是JSR250规范实现的,而Spring通过BeanPostProcessor来提供对JDK规范的支持。
  • @Autowired、@Inject用法基本一样,不同之处为@Autowired有一个required属性,表示该注入是否是必须的,即如果为必须的,则如果找不到对应的bean,就无法注入,无法创建当前bean。
  • @Autowired、@Inject是默认按照类型匹配的,@Resource是按照名称匹配的。如在spring-boot-data项目中自动生成的redisTemplate的bean,是需要通过byName来注入的。如果需要注入该默认的,则需要使用@Resource来注入,而不是@Autowired。
  • 对于@Autowire和@Inject,如果同一类型存在多个bean实例,则需要指定注入的beanName。@Autowired和@Qualifier一起使用,@Inject和@Name一起使用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot集成shiro,MyRealm中无法@Autowired注入Service的问题

    网上说了很多诸如是Spring加载顺序,shiroFilter在Spring自动装配bean之前的问题,其实也有可能忽略如下低级错误. 在ShiroConfiguration中要使用@Bean在ApplicationContext注入MyRealm,不能直接new对象. 道理和Controller中调用Service一样,都要是SpringBean,不能自己new. 错误方式: @Bean(name = "securityManager") public SecurityManager

  • 因Spring AOP导致@Autowired依赖注入失败的解决方法

    发现问题: 之前用springAOP做了个操作日志记录,这次在往其他类上使用的时候,service一直注入失败,找了网上好多内容,发现大家都有类似的情况出现,但是又和自己的情况不太符合.后来总结自己的情况发现:方法为private修饰的,在AOP适配的时候会导致service注入失败,并且同一个service在其他的public方法中就没有这种情况,十分诡异. 解决过程: 结合查阅的资料进行了分析:在org.springframework.aop.support.AopUtils中: publi

  • Spring框架中 @Autowired 和 @Resource 注解的区别

    Spring框架中 @Autowired 和 @Resource 注解的区别 在 spring 框架中,除了使用其特有的注解外,使用基于 JSR-250 的注解,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释. 首先,咱们简单了解 @PostConstruct 和 @PreDestroy 注释: 为了定义一个 bean 的安装和卸载,我们可以使用 init-method 和 destroy-method 参数简单的声明一下 ,其中 init-meth

  • 基于Spring@Autowired注解与自动装配详谈

    1 配置文件的方法 我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. Boss 拥有 Office 和 Car 类型的两个属性: 清单 3. Boss.java package com.baobaotao; public class Boss { private Car car; private Office office; // 省略 get/setter @Override p

  • 详解Spring注解--@Autowired、@Resource和@Service

    什么是注解 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件,那么.xml文件又会非常多.总之这将导致配置文件的可读性与可维护性变得很低 2.在开发中在.java文件和.xml文件之间不断切换,是一件麻烦的事,同时这种思维上的不连贯也会降低开发的效率 为了解决这两个问题,Spring引入了注解,通过"@XXX"的方式,让注解与Java

  • 详解Spring @Autowired 注入小技巧

    今天和同事讨论到Spring自动注入时,发现有这么一段代码特别地困惑,当然大致的原理还是可以理解的,只不过以前从来没有这么用过.想到未来可能会用到,或者未来看别人写的代码时不至于花时间解决同样的困惑,所以小编还是觉得有必要研究记录一下. 一.同一类型注入多次为同一实例 首先让我们先看下这段代码是什么? @Autowired private XiaoMing xiaoming; @Autowired private XiaoMing wanger; XiaoMing.java package co

  • 解决SpringBoot项目使用多线程处理任务时无法通过@Autowired注入bean问题

    最近在做一个"温湿度控制"的项目,项目要求通过用户设定的温湿度数值和实时采集到的数值进行比对分析,因为数据的对比与分析是一个通过前端页面控制的定时任务,经理要求在用户开启定时任务时,单独开启一个线程进行数据的对比分析,并将采集到的温湿度数值存入数据库中的历史数据表,按照我们正常的逻辑应该是用户在请求开启定时任务时,前端页面通过调用后端接口,创建一个新的线程来执行定时任务,然后在线程类中使用 @Autowired 注解注入保存历史数据的service层,在线程类中调用service层保存

  • 解决Springboot @Autowired 无法注入问题

    特别提醒:一定要注意文件结构 WebappApplication 一定要在包的最外层,否则Spring无法对所有的类进行托管,会造成@Autowired 无法注入. 1. 添加工具类获取在 Spring 中托管的 Bean (1)工具类 package com.common; import org.springframework.beans.BeansException; import org.springframework.beans.factory.NoSuchBeanDefinitionE

  • 详解SpringBoot 多线程处理任务 无法@Autowired注入bean问题解决

    在多线程处理问题时,无法通过@Autowired注入bean,报空指针异常, 在线程中为了线程安全,是防注入的,如果要用到这个类,只能从bean工厂里拿个实例. 解决方法如下: 1.创建一个工具类代码: package com.hqgd.pms.common; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.spri

  • 详解Spring依赖注入的三种方式以及优缺点

    目录 0.概述 1.属性注入 1.1 优点分析 1.2 缺点分析 2.Setter 注入 优缺点分析 3.构造方法注入 优点分析 总结 0.概述 在 Spring 中实现依赖注入的常见方式有以下 3 种: 属性注入(Field Injection): Setter 注入(Setter Injection): 构造方法注入(Constructor Injection). 它们的具体使用和优缺点分析如下. 1.属性注入 属性注入是我们最熟悉,也是日常开发中使用最多的一种注入方式,它的实现代码如下:

  • 详解Spring依赖注入:@Autowired,@Resource和@Inject区别与实现原理

    一.spring依赖注入使用方式 @Autowired是spring框架提供的实现依赖注入的注解,主要支持在set方法,field,构造函数中完成bean注入,注入方式为通过类型查找bean,即byType的,如果存在多个同一类型的bean,则使用@Qualifier来指定注入哪个beanName的bean. 与JDK的@Resource的区别:@Resource是基于bean的名字,即beanName,来从spring的IOC容器查找bean注入的,而@Autowried是基于类型byType

  • 详解Angular依赖注入

    目录 概述 一.依赖注入 二.Angular的依赖注入框架 概述 依赖注入:设计模式 依赖:程序里需要的某种类型的对象. 依赖注入框架:工程化的框架 注入器Injector:用它的API创建依赖的实例 Provider:怎样创建?(构造函数,工程函数) Object:组件,模块需要的依赖 依赖性注入进阶=>Angular中依赖注入框架提供父子层次注入型依赖 一.依赖注入 class Id { static getInstance(type: string): Id { return new Id

  • 详解Spring Boot 部署jar和war的区别

    本文介绍了Spring Boot 部署jar和war两种方式的区别,分享给大家,具体如下: 1. packaging的方式不同,一种设置成jar一种是war <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org

  • 详解Spring 参数验证@Validated和@Valid的区别

    Spring Validation验证框架对参数的验证机制提供了@Validated(Spring's JSR-303 规范,是标准 JSR-303 的一个变种),javax提供了@Valid(标准JSR-303规范),配合 BindingResult 可以直接提供参数验证结果.其中对于字段的特定验证注解比如 @NotNull 等网上到处都有,这里不详述 在检验 Controller 的入参是否符合规范时,使用 @Validated 或者 @Valid 在基本验证功能上没有太多区别.但是在分组.

  • 详解Spring中使用@within与@target的区别

    项目里用到@within时,出现了一些问题,使用@target就可以解决,但又会出现一些新的问题,因此本文探讨了在spring中,使用@within和@target的一些区别. 背景 项目里有一个动态切换数据源的功能,我们是用切面来实现的,是基于注解来实现的,但是父类的方法是可以切换数据源的,如果有一个类直接继承这个类,调用这个子类时,这个子类是不能够切换数据源的,除非这个子类重写父类的方法. 模拟项目例子 注解定义: @Target({ElementType.METHOD, ElementTy

  • 详解Spring bean的注解注入之@Autowired的原理及使用

    一.@Autowired 概念: @Autowired 注释,它可以对类成员变量.方法及构造函数进行标注,完成自动装配的工作. 通过 @Autowired的使用来消除 set ,get方法. 在使用@Autowired之前,我们对一个bean配置起属性时,用的是 <property name="属性名" value=" 属性值"/> 使用@Autowired之后,我们只需要在需要使用的地方使用一个@Autowired 就可以了. 代码使用: public

  • 详解Spring的核心机制依赖注入

    详解Spring的核心机制依赖注入 对于一般的Java项目,他们都或多或少有一种依赖型的关系,也就是由一些互相协作的对象构成的.Spring把这种互相协作的关系称为依赖关系.如A组件调用B组件的方法,可称A组件依赖于B组件,依赖注入让Spring的Bean以配置文件组织在一起,而不是以硬编码的方式耦合在一起 一.理解依赖注入 依赖注入(Dependency Injection) = 控制反转(Inversion ofControl,IoC):当某个Java实例(调用者)需另一个Java实例(被调

  • Spring依赖注入(DI)两种方式的示例详解

    目录 一.依赖注入方式 二.setter注入 引用类型 简单类型 三.构造器注入 引用类型 简单类型 参数适配(了解) 四.依赖注入方式选择 一.依赖注入方式 思考:向一个类中传递数据的方式有几种? 普通方法(set方法) 构造方法 思考:依赖注入描述了在容器中建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串呢? 引用类型 简单类型(基本数据类型与String) 依赖注入方式: setter注入 简单类型 引用类型 构造器注入 简单类型 引用类型 二.setter注

  • Spring依赖注入的三种方式实例详解

    Spring依赖注入(DI)的三种方式,分别为: 1. 接口注入 2. Setter方法注入 3. 构造方法注入 下面介绍一下这三种依赖注入在Spring中是怎么样实现的. 首先我们需要以下几个类: 接口 Logic.java 接口实现类 LogicImpl.java 一个处理类 LoginAction.java 还有一个测试类 TestMain.java Logic.java如下: package com.spring.test.di; public interface Logic { pub

随机推荐