Spring Framework的主要特性之一是DI[依赖注入],而实现该方式主要通过配置spring bean的

通常我们会在bean configuration file 中配置程序想要注入的bean 配置,也可以引用配置在其他 file中的bean[通过 ref 引用]。这种方法在需要注入很多bean的时候配置会显得比较繁锁

所以spring提供了 autowired 机制,从而必须定义每一个bean

目前有以下几种方式实现autowired:

  1. autowired byName, 这种方式在 service 中必须实现需要inject的成员变量的setter方法,
    并bean 中配置的bean name 必须和成员变量相同

    1
    2
    <!-- autowiring byName, bean name should be same as the property name -->
    <bean name="employeeServiceByName" class="com.walterlife.springtest.service.EmployeeService" autowire="byName" />
  2. autowired byType, 该种方式下同一种 bean type 只能 配置一次

    1
    2
    <!-- autowiring byType, there should be only one bean definition for the mapping -->
    <bean name="employeeServiceByType" class="com.walterlife.springtest.service.EmployeeService" autowire="byType" />
  3. autowired by constructor, 和 byType类似,只是该种方式是通过构造函数进行注入的

  4. autowired by @Autowired 注解, 使用该种方式,需要配置

    1
    2
    <!-- Enable Annotation based configuration -->
    <context:annotation-config />
  5. @Qualifer, 该注解用来表明@Autowired的参数指定的类型,本身需要带上injected 的bean name

    1
    2
    3
    4
    @Autowired(required=false)
    public EmployeeAutowiredByConstructorService(@Qualifier("employee") Employee employee) {
    this.employee = employee;
    }

下面举例说明以上几种autowired 方式

项目结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SpringAutowired/
├── pom.xml
└── src
└── main
├── java
│   └── com
│   └── walterlife
│   └── springtest
│   ├── App.java
│   ├── model
│   │   └── Employee.java
│   └── service
│   ├── EmployeeAutowiredByConstructorService.java
│   ├── EmployeeAutowiredByTypeService.java
│   └── EmployeeService.java
└── resources
└── spring.xml
通过tree -L 8 -I "target|test" SpringAutowired 命令生成

maven 依赖如下,在pom.xml添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- 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>

添加 Model Bean Class,在bean configuration 中进行初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Employee.java
public class Employee {
private String name;

/**
* @return the name
*/

public String getName() {
return name;
}

/**
* @param name the name to set
*/

public void setName(String name) {
this.name = name;
}
}

创建service class, 用于通过autowired 注入 bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
EmployeeService.java
public class EmployeeService {
private Employee employee;

public EmployeeService(Employee employee) {
System.out.printf("%s\n", "Autowiring by constructer used!!!");
this.employee = employee;
}

public EmployeeService() {
System.out.printf("%s\n", "Default constructer invoked!!!");
}
/**
* @return the employee
*/

public Employee getEmployee() {
return employee;
}

/**
* @param employee the employee to set
*/

// 类中包含该函数,可以使用Autowired byName
public void setEmployee(Employee employee) {
this.employee = employee;
}
}

该 service 可以用于 autowired by type, name, constructor
byType, byName 是通过 setter 方法来注入的,而 byConstructor 是通过constructor 方法注入的

当使用 byType, byName是通过默认构造函数实例化对象的,所以代码中显式的定义了默认构造函数

@Autowired bean autowiring byType

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.walterlife.springtest.service;

import org.springframework.beans.factory.annotation.Autowired;
import com.walterlife.springtest.model.Employee;

public class EmployeeAutowiredByTypeService {
@Autowired
private Employee employee;

/**
* @return the employee
*/

public Employee getEmployee() {
return employee;
}

/**
* @param employee the employee to set
*/

@Autowired
public void setEmployee(Employee employee) {
this.employee = employee;
}
}

留言

Sep 1 2015