Spring @Autowired Annotation

Spring @Autowired注释用于自动依赖注入。Spring框架是基于依赖注入构建的,我们通过spring bean配置文件注入类依赖项。

目录[ 隐藏 ]

  • 1 Spring @Autowired Annotation

    • 1.1 Spring @Autowired Annotation - Maven依赖项
    • 1.2 Spring @Autowired Annotation - Model Bean
    • 1.3 Spring @Autowired Annotation - 服务类
    • 1.4 Spring @Autowired Annotation - 自动装配byType示例
    • 1.5 Spring @Autowired Annotation和@Qualifier Bean通过构造函数自动装配示例
    • 1.6 Spring @Autowired Annotation - Bean配置文件
    • 1.7 Spring @Autowired Annotation - 测试程序

Spring @Autowired Annotation

通常我们在spring bean配置文件中提供bean配置细节,并且我们还使用refattribute 指定将在其他bean中注入的bean 。但Spring框架也提供了自动装配功能,我们不需要明确提供bean注入细节。

我们可以通过不同的方式自动装配一个spring bean。

  1. autowire byName - 对于这种类型的自动装配,setter方法用于依赖注入。此外,变量名应该在我们将注入依赖项的类中和spring bean配置文件中相同。
  2. autowire byType - 对于这种类型的自动装配,使用类类型。因此,spring bean配置文件中只应该为此类型配置一个bean。
  3. autowire by constructor - 这几乎类似于autowire byType,唯一的区别是构造函数用于注入依赖项。
  4. autodeire by autodetect - 如果你使用的是Spring 3.0或更早版本,这是可用的autowire选项之一。此选项由构造函数或byType用于autowire,由Spring容器确定。由于我们已经有这么多选项,因此不推荐使用此选项。我不会在本教程中介绍此选项。
  5. @Autowired注释 - 我们可以使用Spring @Autowired注释进行spring bean自动装配。@Autowired注释可以应用于自动装配byType的变量和方法。我们还可以在构造函数上使用@Autowired注释来构造基于Spring的自动装配。

    要使@Autowired注释起作用,我们还需要在spring bean配置文件中启用基于注释的配置。这可以通过context:annotation-config元素或通过定义类型的bean来完成org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor

  6. @Qualifierannotation - 此注释用于避免bean映射中的冲突,我们需要提供将用于自动装配的bean名称。这样我们就可以避免为同一类型定义多个bean的问题。此注释通常与@Autowired注释一起使用。对于具有多个参数的构造函数,我们可以将此注释与方法中的参数名称一起使用。

默认情况下,Spring bean自动装配已关闭。Spring bean autowire默认值为“default”,表示不执行自动装配。autowire值“no”也有相同的行为。

为了展示Spring Bean自动装配的使用,让我们创建一个简单的Spring Maven项目。我们的最终项目将如下图所示。

让我们逐个研究每个autowire选项。为此,我们将创建一个Model bean和一个服务类,我们将在其中注入模型bean。

Spring @Autowired Annotation - Maven Dependencies

对于spring自动装配,我们不需要添加任何其他依赖项。我们的pom.xml文件具有spring框架核心依赖关系,如下所示。


<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/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.springframework.samples</groupId><artifactId>SpringBeanAutowiring</artifactId><version>0.0.1-SNAPSHOT</version><properties><!-- Generic properties --><java.version>1.6</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><!-- Spring --><spring-framework.version>4.0.2.RELEASE</spring-framework.version><!-- Logging --><logback.version>1.0.13</logback.version><slf4j.version>1.7.5</slf4j.version></properties><dependencies><!-- Spring and Transactions --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring-framework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring-framework.version}</version></dependency><!-- Logging with SLF4J & LogBack --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version><scope>compile</scope></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>${logback.version}</version><scope>runtime</scope></dependency></dependencies>
</project>

Spring @Autowired Annotation - Model Bean

让我们创建一个名为Employee的简单Java Bean。这个bean将有一个带getter和setter方法的属性。我们将在spring bean配置文件中初始化此属性值。


package com.journaldev.spring.autowiring.model;public class Employee {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

Spring @Autowired Annotation - 服务类

让我们创建我们的服务类,我们将通过spring自动装配注入Employee bean。


package com.journaldev.spring.autowiring.service;import com.journaldev.spring.autowiring.model.Employee;public class EmployeeService {private Employee employee;// constructor is used for autowire by constructorpublic EmployeeService(Employee emp) {System.out.println("Autowiring by constructor used");this.employee = emp;}// default constructor to avoid BeanInstantiationException for autowire// byName or byTypepublic EmployeeService() {System.out.println("Default Constructor used");}// used for autowire byName and byTypepublic void setEmployee(Employee emp) {this.employee = emp;}public Employee getEmployee() {return this.employee;}
}

我们将使用相同的服务类来执行Spring自动装配byName,byType和构造函数。setter方法将用于弹簧自动装配byName和byType,而基于构造函数的注入将由构造函数autowire属性使用。

当我们使用spring autowire byName或byType时,使用默认构造函数。这就是我们为EmployeeService bean明确定义默认构造函数的原因。

Spring @Autowired Annotation - 自动装配byType示例

让我们用Spring @Autowired注释创建一个单独的类,用于自动装配byType。


package com.journaldev.spring.autowiring.service;import org.springframework.beans.factory.annotation.Autowired;import com.journaldev.spring.autowiring.model.Employee;public class EmployeeAutowiredByTypeService {//Autowired annotation on variable/setters is equivalent to autowire="byType"@Autowiredprivate Employee employee;@Autowiredpublic void setEmployee(Employee emp){this.employee=emp;}public Employee getEmployee(){return this.employee;}
}

请注意,我已经使用Spring @Autowired注释注释了Employee变量和它的setter方法,但是只有其中一个足以用于spring bean自动装配。

Spring @Autowired Annotation和@Qualifier Bean通过构造函数自动装配示例

让我们创建另一个服务类,我们将使用@Autowired注释进行基于构造函数的注入。我们还将看到@Qualifier注释用法。


package com.journaldev.spring.autowiring.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;import com.journaldev.spring.autowiring.model.Employee;public class EmployeeAutowiredByConstructorService {private Employee employee;//Autowired annotation on Constructor is equivalent to autowire="constructor"@Autowired(required=false)public EmployeeAutowiredByConstructorService(@Qualifier("employee") Employee emp){this.employee=emp;}public Employee getEmployee() {return this.employee;}
}

当这个bean将被Spring框架初始化时,名为“employee”的bean将用于自动装配。Spring @Autowired注释除了一个参数“required”,它是一个布尔值,默认值为TRUE。我们可以将它定义为“false”,这样如果找不到适合自动装配的bean,spring框架就不会抛出任何异常。

Spring @Autowired Annotation - Bean配置文件

Spring bean配置文件是任何spring应用程序的主要部分,让我们看一下spring bean配置文件的外观,然后我们将查看它的每个部分。


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"default-autowire="byName" default-autowire-candidates="*" ><bean name="employee" class="com.journaldev.spring.autowiring.model.Employee"><property name="name" value="Pankaj"></property>
</bean><bean name="employee1" class="com.journaldev.spring.autowiring.model.Employee" autowire-candidate="false"><property name="name" value="Dummy Name"></property>
</bean><!-- autowiring byName, bean name should be same as the property name -->
<bean name="employeeServiceByName" class="com.journaldev.spring.autowiring.service.EmployeeService" autowire="byName" /><!-- autowiring byType, there should be only one bean definition for the mapping -->
<bean name="employeeServiceByType" class="com.journaldev.spring.autowiring.service.EmployeeService" autowire="byType" /><!-- autowiring by constructor -->
<bean name="employeeServiceConstructor" class="com.journaldev.spring.autowiring.service.EmployeeService" autowire="constructor" /><!-- Enable Annotation based configuration -->
<context:annotation-config /><!-- using @Autowiring annotation in below beans, byType and constructor -->
<bean name="employeeAutowiredByTypeService" class="com.journaldev.spring.autowiring.service.EmployeeAutowiredByTypeService" />
<bean name="employeeAutowiredByConstructorService" class="com.journaldev.spring.autowiring.service.EmployeeAutowiredByConstructorService" />
</beans>

关于spring bean配置文件的重点是:

  • beans元素default-autowire用于定义默认的自动装配方法。在这里,我将默认的自动装配方法定义为byName。
  • beans元素default-autowire-candidates用于为可用于自动装配的bean名称提供模式。为简单起见,我允许所有bean定义都符合自动装配的条件,但是如果我们可以为自动装配定义一些模式。例如,如果我们只想要自动装配DAO bean定义,我们可以将其指定为default-autowire-candidates="*DAO"
  • autowire-candidate="false"用于bean定义,使其不符合自动装配的条件。当我们为单个类型提供多个bean定义时,它们很有用,我们希望其中一些不是自动装配的。例如,在上面的spring bean配置中,“employee1”bean不会用于自动装配。
  • autowire属性byName,byType和构造函数是自我理解的,没什么可解释的。
  • context:annotation-config用于启用基于注释的配置支持。请注意,employeeAutowiredByTypeService和employeeAutowiredByConstructorService bean没有autowire属性。

Spring @Autowired Annotation - 测试程序

既然我们的弹簧应用已经准备好了所有类型的弹簧自动装配,那么让我们编写一个简单的测试程序,看看它是否按预期工作。


package com.journaldev.spring.autowiring.main;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.journaldev.spring.autowiring.service.EmployeeAutowiredByConstructorService;
import com.journaldev.spring.autowiring.service.EmployeeAutowiredByTypeService;
import com.journaldev.spring.autowiring.service.EmployeeService;public class SpringMain {public static void main(String[] args) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");EmployeeService serviceByName = ctx.getBean("employeeServiceByName", EmployeeService.class);System.out.println("Autowiring byName. Employee Name="+serviceByName.getEmployee().getName());EmployeeService serviceByType = ctx.getBean("employeeServiceByType", EmployeeService.class);System.out.println("Autowiring byType. Employee Name="+serviceByType.getEmployee().getName());EmployeeService serviceByConstructor = ctx.getBean("employeeServiceConstructor", EmployeeService.class);System.out.println("Autowiring by Constructor. Employee Name="+serviceByConstructor.getEmployee().getName());//printing hashcode to confirm all the objects are of different typeSystem.out.println(serviceByName.hashCode()+"::"+serviceByType.hashCode()+"::"+serviceByConstructor.hashCode());//Testing @Autowired annotationsEmployeeAutowiredByTypeService autowiredByTypeService = ctx.getBean("employeeAutowiredByTypeService",EmployeeAutowiredByTypeService.class);System.out.println("@Autowired byType. Employee Name="+autowiredByTypeService.getEmployee().getName());EmployeeAutowiredByConstructorService autowiredByConstructorService = ctx.getBean("employeeAutowiredByConstructorService",EmployeeAutowiredByConstructorService.class);System.out.println("@Autowired by Constructor. Employee Name="+autowiredByConstructorService.getEmployee().getName());ctx.close();}
}

程序很简单,我们只是创建spring应用程序上下文并使用它来获取不同的bean并打印员工姓名。

当我们运行上面的应用程序时,我们得到以下输出


Mar 31, 2014 10:41:58 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3fa99295: startup date [Mon Mar 31 22:41:58 PDT 2014]; root of context hierarchy
Mar 31, 2014 10:41:58 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring.xml]
Default Constructor used
Default Constructor used
Autowiring by constructor used
Autowiring byName. Employee Name=Pankaj
Autowiring byType. Employee Name=Pankaj
Autowiring by Constructor. Employee Name=Pankaj
21594592::15571401::1863015320
@Autowired byType. Employee Name=Pankaj
@Autowired by Constructor. Employee Name=Pankaj
Mar 31, 2014 10:41:58 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@3fa99295: startup date [Mon Mar 31 22:41:58 PDT 2014]; root of context hierarchy

正如您所看到的,对于autowire byName和byType,默认的no-args构造函数用于初始化bean。对于构造函数的autowire,使用基于参数的构造函数。

从所有变量的哈希码,我们已经确认所有的spring bean都是不同的对象,而不是指同一个对象。

由于我们从符合条件的bean列表中删除了“employee1”以进行自动装配,因此bean映射中没有混淆。如果我们autowire-candidate="false"从“employee1”定义中删除,我们将在执行上述main方法时得到以下错误消息。


Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'employeeServiceByType' defined in class path resource [spring.xml]: Unsatisfied dependency expressed through bean property 'employee': : No qualifying bean of type [com.journaldev.spring.autowiring.model.Employee] is defined: expected single matching bean but found 2: employee,employee1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.journaldev.spring.autowiring.model.Employee] is defined: expected single matching bean but found 2: employee,employee1at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1278)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1170)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)at com.journaldev.spring.autowiring.main.SpringMain.main(SpringMain.java:12)
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.journaldev.spring.autowiring.model.Employee] is defined: expected single matching bean but found 2: employee,employee1at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:967)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1263)... 13 more

这就是Spring @Autowired Annotation和Spring自动装配功能的全部内容,请从下面链接下载示例项目并进行分析以了解更多信息。

Spring @Autowired Annotation相关推荐

  1. Spring @Autowired Annotation教程

    Spring @Autowired Annotation教程 Spring @Autowired注释用于自动依赖注入.Spring框架是基于依赖注入构建的,我们通过spring bean配置文件注入类 ...

  2. Spring @Autowired批注

    Spring @Autowired annotation is used for automatic dependency injection. Spring framework is built o ...

  3. spring autowired idea都匹配上了_你清楚这几个Spring常用注解吗?

    作者:平凡希http://cnblogs.com/xiaoxi/p/5935009.html 传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点: 如 ...

  4. Spring @Autowired 注释

    转载自  Spring @Autowired 注释 Spring @Autowired 注释 @Autowired 注释对在哪里和如何完成自动连接提供了更多的细微的控制. @Autowired 注释可 ...

  5. 使用Spring @Autowired List的责任链

    在Spring 3.1中,有一种方法可以自动填充类型化的List,这在您想在代码中稍微进行去耦和清理时非常方便. 为了向您展示它是如何工作的,我将实现一个简单的责任链,该责任链将为通过的用户打印一些问 ...

  6. 为什么我的Spring @Autowired字段为空?

    本文翻译自:Why is my Spring @Autowired field null? Note: This is intended to be a canonical answer for a ...

  7. Spring @Autowired 用法

    Spring @Autowired 用法 首先看下@Component ```举例 1 :``` ```举例 2 :``` 验证是否调用的是默认构造器 ```如何,在启动的时候执行有参数的构造函数?? ...

  8. Wiring in Spring: @Autowired, @Resource and @Inject

    Overview 我们将演示如何使用与依赖注入相关的注释,即@Resource.@Inject和@Autowired注释.这些注释为类提供了一种声明性的方式来解析依赖关系: @Autowired Ar ...

  9. Wiring in Spring: @Autowired, @Resource and @Inject 三种注解实现依赖注入

    原文链接:Wiring in Spring: @Autowired, @Resource and @Inject 1. Overview 概述 In this Spring Framework tut ...

最新文章

  1. 详尽 | PyTorch动态图解析
  2. 在Tomcat7.0中设置默认服务器和不加端口名访问
  3. vim中的 recording
  4. Secondary Namenode的Check point机制以及Namenode、Datanode工作机制说明
  5. 如何查看和转移 Windows Server 2003 中的 FSMO 角色
  6. 数据分析只能当一辈子取数机?可能你缺少这个基础思维
  7. 如何使用jQuery更改超链接的href
  8. Git详解之二 Git基础(第二部分)
  9. android-生命周期和GC
  10. 《从问题到程序:用Python学编程和计算》——1.4 练习
  11. 计算机的it入门知识,IT基础知识入门课程.ppt
  12. 计网-基于Cisco模拟器
  13. Java BigDecimal 的舍入模式(RoundingMode)详解
  14. 小程序中如何关注公众号
  15. 2019年字节跳动2020届秋招在线笔试真题(后端开发工程师)
  16. 自己制作Chrome绿色版本。
  17. 宝宝长牙发烧怎么办?会自己退吗?
  18. cadence——基本操作1
  19. Linux笔记001 初识Linux
  20. CSDN访客统计(不用量子恒道)

热门文章

  1. Linux: 利用 Alpine 在命令行里访问 Gmail
  2. Adaptive Images : 为不同的屏幕尺寸提供不同的图片
  3. Linux中的Total Video Converter——超级音视频转换软件:Winff
  4. 安装MongoDB Install MongoDB on Ubuntu
  5. 13个您应该安装的WordPress插件
  6. 并查集——畅通工程(hdu1232)
  7. git 命令之 如何将本地新建分支推到服务器上
  8. Linux查看负载 uptime,w ,top,iostat 命令
  9. C++——有关chrono库的duration
  10. 【设计模式】设计模式C++编程实现之观察者模式(ObserverPattern)