Spring @Autowired 注释用于自动依赖注射。 Spring framework是建立在 依赖注射上,我们通过春豆配置文件注入类依赖。
春天 自我评论
Usually we provide bean configuration details in the spring bean configuration file and we also specify the beans that will be injected in other beans using
ref
attribute. But Spring framework provides autowiring features too where we don't need to provide bean injection details explicitly. There are different ways through which we can autowire a spring bean.
- 自动接线方式Name - 对于这种自动接线方式,在依赖性注射时使用定接方法。 另外,在我们将注入依赖的类别和春季豆类配置文件中,变量名称应该相同。 () )2. 由Type自动接线 - 对于这类自動接線,会使用类类型. 因此,春豆配置文件中应该只配置了一种豆类. () )3. 由构造器自动接线——这与由Type自动接线几乎相似,唯一的区别是构造器用于注入依赖性. (
- 由自动检测自动接线 - 如果您在 Spring 3. 0 或 上等版本, 这是可用的自动接线选项之一 。 此选项被用在由Spring容器确定的由构造器或由Type所决定的自動接線上. 因为我们已经有这么多的选择,这个选择被贬低了. 我将不在此教程中覆盖此选项 。 5。 {Autowired' 注释 - 我们可以使用 Spring @ Autowired 注释来进行春豆自旋 。 @ Autowired 注释可以被应用到变量和被Type自动接通的方法上. 我们还可以使用 @ Autowired 对建构器的注释 用于基于建构器的弹簧自动接通 。 @ Autowired 注释要工作, 我们还需要在春季豆配置文件中启用基于注释的配置 。 这可以通过context:annotation-config元素或定义"org.springframework.beans.factory.annotation.Autowired AnnotationBeanPostProcessor. 6"的豆子"注释"来完成. 这种注解被用来避免豆类映射中的冲突,我们需要提供用于自传的豆名. 这样我们可以避免多种豆类被定义为同类型的问题. 此注释通常与 @ Autowired 注释相配合 。 对于有多个参数的构造者,我们可以使用这个注释,在方法中加上参数名. (_) (英语)
By default spring bean autowiring is turned off. Spring bean autowire default value is "default" that means no autowiring is to be performed. autowire value "no" also have the same behavior. To showcase the use of Spring Bean autowiring, let's create a simple Spring Maven project. Our final project will look like below image. Let's look into each of the autowire options one by one. For that we will create a Model bean and a service class where we will inject the model bean.
春天 @Autowired 注释 - Maven 依赖
对于春天自动化,我们不需要添加任何额外的依赖性. 我们的 pom.xml 文件具有春天框架核心依赖性,并且看起来如下。
1<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
3 <modelVersion>4.0.0</modelVersion>
4 <groupId>org.springframework.samples</groupId>
5 <artifactId>SpringBeanAutowiring</artifactId>
6 <version>0.0.1-SNAPSHOT</version>
7
8 <properties>
9
10 <!-- Generic properties -->
11 <java.version>1.6</java.version>
12 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
14
15 <!-- Spring -->
16 <spring-framework.version>4.0.2.RELEASE</spring-framework.version>
17
18 <!-- Logging -->
19 <logback.version>1.0.13</logback.version>
20 <slf4j.version>1.7.5</slf4j.version>
21
22 </properties>
23
24 <dependencies>
25 <!-- Spring and Transactions -->
26 <dependency>
27 <groupId>org.springframework</groupId>
28 <artifactId>spring-context</artifactId>
29 <version>${spring-framework.version}</version>
30 </dependency>
31 <dependency>
32 <groupId>org.springframework</groupId>
33 <artifactId>spring-tx</artifactId>
34 <version>${spring-framework.version}</version>
35 </dependency>
36
37 <!-- Logging with SLF4J & LogBack -->
38 <dependency>
39 <groupId>org.slf4j</groupId>
40 <artifactId>slf4j-api</artifactId>
41 <version>${slf4j.version}</version>
42 <scope>compile</scope>
43 </dependency>
44 <dependency>
45 <groupId>ch.qos.logback</groupId>
46 <artifactId>logback-classic</artifactId>
47 <version>${logback.version}</version>
48 <scope>runtime</scope>
49 </dependency>
50
51 </dependencies>
52</project>
春天 @Autowired 注释 - 模型 Bean
让我们创建一个简单的Java Bean,名为Employee。这个Bean将有一个单一的属性,使用getter和setter方法。
1package com.journaldev.spring.autowiring.model;
2
3public class Employee {
4
5 private String name;
6
7 public String getName() {
8 return name;
9 }
10
11 public void setName(String name) {
12 this.name = name;
13 }
14}
春天 @Autowired 注释 - 服务类
让我们创建我们的服务类,在那里我们将通过春季自动灌输注射员工豆。
1package com.journaldev.spring.autowiring.service;
2
3import com.journaldev.spring.autowiring.model.Employee;
4
5public class EmployeeService {
6
7 private Employee employee;
8
9 // constructor is used for autowire by constructor
10 public EmployeeService(Employee emp) {
11 System.out.println("Autowiring by constructor used");
12 this.employee = emp;
13 }
14
15 // default constructor to avoid BeanInstantiationException for autowire
16 // byName or byType
17 public EmployeeService() {
18 System.out.println("Default Constructor used");
19 }
20
21 // used for autowire byName and byType
22 public void setEmployee(Employee emp) {
23 this.employee = emp;
24 }
25
26 public Employee getEmployee() {
27 return this.employee;
28 }
29}
我们将使用相同的服务类来执行由名称、由类型和由构建者执行的春天自动驾驶。设置方法将用于由名称和由类型进行春天自动驾驶,而基于构建者的注入将由构建者自动驾驶属性使用。
春天 @Autowired 注释 - autowiring byType 示例
让我们用 Spring @Autowired 注释创建一个单独的类,用于 autowiring byType。
1package com.journaldev.spring.autowiring.service;
2
3import org.springframework.beans.factory.annotation.Autowired;
4
5import com.journaldev.spring.autowiring.model.Employee;
6
7public class EmployeeAutowiredByTypeService {
8
9 //Autowired annotation on variable/setters is equivalent to autowire="byType"
10 @Autowired
11 private Employee employee;
12
13 @Autowired
14 public void setEmployee(Employee emp){
15 this.employee=emp;
16 }
17
18 public Employee getEmployee(){
19 return this.employee;
20 }
21}
请注意,我已经注明了员工变量和它使用春季 @Autowired 注释的 setter 方法,但仅其中一个是足够的春季豆子自动连接。
春天 @Autowired 注释和 @Qualifier Bean autowiring 由 constructor 示例
让我们创建另一个服务类,在那里我们将使用 @Autowired 注释用于基于构建器的注射。
1package com.journaldev.spring.autowiring.service;
2
3import org.springframework.beans.factory.annotation.Autowired;
4import org.springframework.beans.factory.annotation.Qualifier;
5
6import com.journaldev.spring.autowiring.model.Employee;
7
8public class EmployeeAutowiredByConstructorService {
9
10 private Employee employee;
11
12 //Autowired annotation on Constructor is equivalent to autowire="constructor"
13 @Autowired(required=false)
14 public EmployeeAutowiredByConstructorService(@Qualifier("employee") Employee emp){
15 this.employee=emp;
16 }
17
18 public Employee getEmployee() {
19 return this.employee;
20 }
21}
当这个豆子由 Spring 框架初始化时,将使用名为员工
的豆子用于自动连接。春天 @Autowired 注释除了一项必要
的参数,即具有默认值为 TRUE 的 Boolean。
Spring @Autowired 注释 - Bean 配置文件
春豆配置文件是任何春豆应用程序的主要部分,让我们看看我们的春豆配置文件看起来如何,然后我们将看看它的每个部分。
1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="https://www.springframework.org/schema/beans"
3 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
4 xmlns:context="https://www.springframework.org/schema/context"
5 xsi:schemaLocation="https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
6 https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-4.0.xsd"
7
8 default-autowire="byName" default-autowire-candidates="*" >
9
10<bean name="employee" class="com.journaldev.spring.autowiring.model.Employee">
11 <property name="name" value="Pankaj"></property>
12</bean>
13
14<bean name="employee1" class="com.journaldev.spring.autowiring.model.Employee" autowire-candidate="false">
15 <property name="name" value="Dummy Name"></property>
16</bean>
17
18<!-- autowiring byName, bean name should be same as the property name -->
19<bean name="employeeServiceByName" class="com.journaldev.spring.autowiring.service.EmployeeService" autowire="byName" />
20
21<!-- autowiring byType, there should be only one bean definition for the mapping -->
22<bean name="employeeServiceByType" class="com.journaldev.spring.autowiring.service.EmployeeService" autowire="byType" />
23
24<!-- autowiring by constructor -->
25<bean name="employeeServiceConstructor" class="com.journaldev.spring.autowiring.service.EmployeeService" autowire="constructor" />
26
27<!-- Enable Annotation based configuration -->
28<context:annotation-config />
29
30<!-- using @Autowiring annotation in below beans, byType and constructor -->
31<bean name="employeeAutowiredByTypeService" class="com.journaldev.spring.autowiring.service.EmployeeAutowiredByTypeService" />
32<bean name="employeeAutowiredByConstructorService" class="com.journaldev.spring.autowiring.service.EmployeeAutowiredByConstructorService" />
33</beans>
关于春豆配置文件的重要点是:
- ** 豆** 元素`默认-自动线'用于定义默认自动线接方法。 这里我定义了默认的自动连接方法Name (_) ( )* ** 豆** 元素 " 默认-自动电线-候选人 " 用于提供豆名的模式,可用于自动接通。 为了简单起见,我允许所有豆类定义都符合自动焊接的条件,但是如果我们能定义一些自动焊接的模式. 例如,如果我们只想要DAO豆定义用于自動接通,我们可以将其指定为"默认-自动接通-canidates="*DAO".
自动接通-candidate="假"'被用在一个豆定义中,使其不符合自动接通的资格. 当我们对单一类型有多个豆类定义,并且我们希望其中的一些定义不要被自动接通时,这是有用的. 例如,在上方的"春季豆"配置中"雇员1"豆将不用于自動接線. *自動接線屬性由Name,byType和构造器自取自解,并没有什么可解释的. (_) ) *
context:an Notation-config' 用于启用基于notation的配置支持. 注意员工AutowiredByTypeService和员工AutowiredByConstructionersService豆没有自动电线属性. ( (英语)
春天 @Autowired 注释 - 测试计划
现在,我们的春季应用程序已经准备好所有类型的春季自动连接,让我们写一个简单的测试计划,看看它是否按预期运作。
1package com.journaldev.spring.autowiring.main;
2
3import org.springframework.context.support.ClassPathXmlApplicationContext;
4
5import com.journaldev.spring.autowiring.service.EmployeeAutowiredByConstructorService;
6import com.journaldev.spring.autowiring.service.EmployeeAutowiredByTypeService;
7import com.journaldev.spring.autowiring.service.EmployeeService;
8
9public class SpringMain {
10
11 public static void main(String[] args) {
12 ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
13
14 EmployeeService serviceByName = ctx.getBean("employeeServiceByName", EmployeeService.class);
15
16 System.out.println("Autowiring byName. Employee Name="+serviceByName.getEmployee().getName());
17
18 EmployeeService serviceByType = ctx.getBean("employeeServiceByType", EmployeeService.class);
19
20 System.out.println("Autowiring byType. Employee Name="+serviceByType.getEmployee().getName());
21
22 EmployeeService serviceByConstructor = ctx.getBean("employeeServiceConstructor", EmployeeService.class);
23
24 System.out.println("Autowiring by Constructor. Employee Name="+serviceByConstructor.getEmployee().getName());
25
26 //printing hashcode to confirm all the objects are of different type
27 System.out.println(serviceByName.hashCode()+"::"+serviceByType.hashCode()+"::"+serviceByConstructor.hashCode());
28
29 //Testing @Autowired annotations
30 EmployeeAutowiredByTypeService autowiredByTypeService = ctx.getBean("employeeAutowiredByTypeService",EmployeeAutowiredByTypeService.class);
31
32 System.out.println("@Autowired byType. Employee Name="+autowiredByTypeService.getEmployee().getName());
33
34 EmployeeAutowiredByConstructorService autowiredByConstructorService = ctx.getBean("employeeAutowiredByConstructorService",EmployeeAutowiredByConstructorService.class);
35
36 System.out.println("@Autowired by Constructor. Employee Name="+autowiredByConstructorService.getEmployee().getName());
37
38 ctx.close();
39 }
40}
该程序很简单,我们只是创建春季应用程序的背景,并使用它来获取不同的豆类和打印员工的名称。
1Mar 31, 2014 10:41:58 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
2INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3fa99295: startup date [Mon Mar 31 22:41:58 PDT 2014]; root of context hierarchy
3Mar 31, 2014 10:41:58 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
4INFO: Loading XML bean definitions from class path resource [spring.xml]
5Default Constructor used
6Default Constructor used
7Autowiring by constructor used
8Autowiring byName. Employee Name=Pankaj
9Autowiring byType. Employee Name=Pankaj
10Autowiring by Constructor. Employee Name=Pankaj
1121594592::15571401::1863015320
12@Autowired byType. Employee Name=Pankaj
13@Autowired by Constructor. Employee Name=Pankaj
14Mar 31, 2014 10:41:58 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
15INFO: 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 构建器被用来初始化豆子。对于 autowire by constructor,使用了基于参数的构建器。从所有变量的哈希代码中,我们确认所有的春豆都是不同的对象,而不是指相同的对象。由于我们从可选豆类列表中删除了employee1
,所以没有混淆。如果我们从employee1
定义中删除autowire-candidate="false
,我们在执行上面的主要方法时会收到以下错误信息。
1Exception 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,employee1
2 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1278)
3 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1170)
4 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
5 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
6 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
7 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
8 at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
9 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
10 at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
11 at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
12 at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
13 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
14 at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
15 at com.journaldev.spring.autowiring.main.SpringMain.main(SpringMain.java:12)
16Caused 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,employee1
17 at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:967)
18 at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:855)
19 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByType(AbstractAutowireCapableBeanFactory.java:1263)
20 ... 13 more
对于春季 @Autowired 注释和春季自动注释功能来说,请从下面的链接下载示例项目,并分析它以了解更多。