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 Bean自动装配项目

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 Data JPA教程

    在Java类或对象与关系数据库之间管理数据是一项非常繁琐且棘手的任务. DAO层通常包含许多样板代码,应简化这些样板代码,以减少代码行数并使代码可重复使用. 在本教程中,我们将讨论Spring数据的J ...

  4. Spring AMQP ActiveMQ教程

    Spring AMQP ActiveMQ教程 欢迎使用Spring AMQP ActiveMQ教程.之前我们研究过安装Apache ActiveMQ服务器.今天我们将创建一个Spring应用程序来使用 ...

  5. Spring JSF集成教程

    Spring JSF集成教程 欢迎来到Spring JSF集成教程.JSF是一个基于组件的框架,非常注重用户界面.而Spring框架核心原则是依赖注入.因此,将JSF与Spring框架集成是有意义的, ...

  6. Spring IoC,Spring Bean示例教程

    Spring IoC,Spring Bean示例教程 欢迎来到Spring IoC示例教程.Spring Framework基于Inversion of Control原理.依赖注入是在应用程序中实现 ...

  7. Spring入门详细教程(二)

    前言 本篇紧接着spring入门详细教程(一),建议阅读本篇前,先阅读第一篇.链接如下: Spring入门详细教程(一) https://www.cnblogs.com/jichi/p/1016553 ...

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

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

  9. Spring @Autowired 注释

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

最新文章

  1. 编程之美2.10:寻找数组中的最大值和最小值
  2. ibatis 的 This SQL map does not contain a MappedStatement的错误
  3. Elasticsearch分页查询Fromamp;Size VS scroll
  4. java图片裁剪并保存_java裁剪图片并保存的示例分享
  5. java socket 浏览器_Socket实现Java和浏览器交互。
  6. win10 专业版安装系统
  7. 【精品课设】经典PID与模糊PID控制的对比与分析(一)
  8. C语言:链表(动态)创建之头插法和尾插法
  9. office VBA 学习
  10. linux实现文件共享的方式,Linux文件共享的实现方式
  11. 三星970PRO用于高速采集存储系统
  12. 你必须知道的89个操作系统核心概念
  13. 社区医院信息系统的设计与实现
  14. 利用函数模板解决双倍功能
  15. Python choice() 函数语法及参数介绍
  16. 作为 PM,我从小就对那些奇葩需求充满好奇
  17. 瑞萨单片机之data flash的使用(五)
  18. SpringBoot框架搭建(redis多数据源+数据库多数据源+全局异常捕获)
  19. Spring官网仓库下载地址
  20. mof定制材料|氨基功能化修饰PIM-1/MOF|乙二胺四乙酸(EDTA)修饰MOF(UiO-66)|Mn–MOF修饰为荧光Eu~(3+)@Mn–MOF

热门文章

  1. python——VS2017开发python与python3.6更新特性
  2. NSGA2算法及其代码
  3. nginx访问日志常用变量
  4. Leetcode算法题(C语言)2
  5. 【matplotlib】远程服务器使用报错 $DISPLAY
  6. SpringBoot—启动报错Exception in thread “main“ java.lang.ClassNotFoundException
  7. Java—一篇读懂java集合(Collection/Map)及Lambda表达式
  8. Java-主方法main()的解析
  9. 区块链技术学习之-简单加密货币-高飞币
  10. 单例模式 c# 1214