Spring框架为一个bean配置依赖注入的四种方式:属性注入、构造方法注入、工厂注入、泛型依赖注入。
1、属性注入:属性方法注入利用setXxx() 方法注入 Bean 的属性值或者依赖对象,由于属性注入方式具有可选择性和灵活性高的优点,因此属性注入是实际项目中最常采用的注入方式 。首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性。
一个People的entity对象:
1 package com.java1234.entity;
2
3 public class People {
4
5 private int id;
6 private String name;
7 private int age;
8
9 public People(int id, String name, int age) {
10 super();
11 this.id = id;
12 this.name = name;
13 this.age = age;
14 }
15
16 public People() {
17 super();
18 // TODO Auto-generated constructor stub
19 }
20
21 public int getId() {
22 return id;
23 }
24 public void setId(int id) {
25 this.id = id;
26 }
27 public String getName() {
28 return name;
29 }
30 public void setName(String name) {
31 this.name = name;
32 }
33 public int getAge() {
34 return age;
35 }
36 public void setAge(int age) {
37 this.age = age;
38 }
39
40 @Override
41 public String toString() {
42 return "People [id=" + id + ", name=" + name + ", age=" + age + "]";
43 }
44
45
46
47 }
beans.xml配置文件:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans.xsd">
6
7 <bean id="people" class="com.java1234.entity.People"></bean>
8 <!-- 属性注入 :给一个bean对象的属性赋值-->
9 <bean id="people2" class="com.java1234.entity.People">
10 <property name="id" value="123456"></property>
11 <property name="name" value="baozi"></property>
12 <property name="age" value="12"></property>
13 </bean>
14 </beans>
一个测试程序:
1 package com.java1234.Test;
2
3 import org.springframework.context.support.ClassPathXmlApplicationContext;
4
5 import com.java1234.entity.People;
6
7
8 public class Test {
9 public static void main(String[] args) {
10 @SuppressWarnings("resource")
11 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
12 People people = (People)applicationContext.getBean("people");
13 System.out.println(people);
14 //属性注入:用于给bean对象的属性赋值
15 People people2 = (People)applicationContext.getBean("people2");
16 System.out.println(people2);
17
18 }
2、构造方法注入:首先要保证被注入的bean要有包含全部属性的构造方法,然后再在配置文件中配置该类的bean,并配置构造器,在配置构造器中用到了<constructor-arg>节点,该节点有四个属性:
· index是索引,指定注入的属性,从0开始,如:0代表personDao,1代表str属性;
· type是指该属性所对应的类型,如Persondao对应的是com.aptech.dao.PersonDAO;
· ref 是指引用的依赖对象;
· value 当注入的不是依赖对象,而是基本数据类型时,就用value;
一个People的entity对象:同上
beans.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--只要是通过构造函数注入,在bean对象里边一定要有一个包含全部属性的构造方法 -->
<!-- 1、构造方法注入(通过类型注入) -->
<bean id="people3" class="com.java1234.entity.People">
<constructor-arg type="int" value="654321"></constructor-arg>
<constructor-arg type="String" value="lhy"></constructor-arg>
<constructor-arg type="int" value="26"></constructor-arg>
</bean>
<!-- 2、构造方法注入(通过索引值注入) -->
<bean id="people4" class="com.java1234.entity.People">
<constructor-arg index="0" value="147"></constructor-arg>
<constructor-arg index="1" value="yang"></constructor-arg>
<constructor-arg index="2" value="1"></constructor-arg>
</bean>
<!-- 3、构造方法注入(联合使用类型和索引值注入) -->
<bean id="people5" class="com.java1234.entity.People">
<constructor-arg type="int" index="0" value="258"></constructor-arg>
<constructor-arg type="String" index="1" value="Li"></constructor-arg>
<constructor-arg type="int" index="2" value="2"></constructor-arg>
</bean>
</beans>
一个测试程序:
1 package com.java1234.Test;
2
3 import org.springframework.context.support.ClassPathXmlApplicationContext;
4
5 import com.java1234.entity.People;
6
7
8 public class Test {
9 public static void main(String[] args) {
10 @SuppressWarnings("resource")
11 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
12 //构造方法注入-->通过bean对象属性类型的方法给属性赋值
13 People people3 = (People)applicationContext.getBean("people3");
14 System.out.println(people3);
15 //构造方法注入-->通过bean对象属性索引值的方法给属性赋值
16 People people4 = (People)applicationContext.getBean("people4");
17 System.out.println(people4);
18 //构造方法注入-->联合使用两种方法给bean对象属性赋值
19 People people5 = (People)applicationContext.getBean("people5");
20 System.out.println(people5);
21
22 }
在Spring中,注入依赖对象可以采用手工装配或自动装配,在实际应用开发中建议使用手工装配,因为自动装配会产生许多未知情况,开发人员无法预见最终的装配结果。手工装配依赖对象又分为两种方式:
- 一种是在XML文件中,通过在bean节点下配置;如上面讲到的使用属性方法注入依赖对象和使用构造器方法注入依赖对象都是这种方式。
- 另一种就是在java代码中使用注解的方式进行装配,在代码中加入@Resource或者@Autowired、
-
- Autowired是自动注入,自动从spring的上下文找到合适的bean来注入
- Resource用来指定名称注入
- Qualifier和Autowired配合使用,指定bean的名称,如
1 @Autowired
2 @Qualifier("userDAO")
3 private UserDAO userDAO;
怎样使用注解的方式来为某个bean注入依赖对象呢?
第一、我们需要在Spring容器的配置文件beans.xml文件中配置以下信息,这些信息是一个Spring配置文件的模板:
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 <beans
4
5 xmlns="http://www.springframework.org/schema/beans"
6
7 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
8
9 xmlns:context="http://www.springframework.org/schema/context"
10
11 xmlns:p="http://www.springframework.org/schema/p"
12
13 xsi:schemaLocation="http://www.springframework.org/schema/beans
14 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
15 http://www.springframework.org/schema/context
16 http://www.springframework.org/schema/context/spring-context-2.5.xsd
17 ">
18
19 </beans>
注意:只有配置了<beans></beans>标签的代码才可以引入注解的命名空间,否则报错。
第二、在配置文件中打开<context:annotation-config>节点,告诉Spring容器可以用注解的方式注入依赖对象;其在配置文件中的代码如下:
1 <beans>
2
3 ……
4
5 <context:annotation-config></context:annotation-config>
6
7 ……
8
9 </beans>
第三,在配置文件中配置bean对象(这个就是对bean对象进行正常的装配);
第四,在需要依赖注入的UserBizImpl类中,声明一个依赖对象,不用生成该依赖对象的setter方法,并且为该对象添加注解:
1 public class UserBizImpl implements UserBiz {
2
3 @Resource(name="userDao")
4
5 private UserDAO userDao = null;
6
7 public void addUser() {
8
9 this.userDao.addUser();
10
11 }
12
13 }
备注:使用注解的方式对依赖进行注入一般有两种写法:使用@Autowired或者@Resource。两者的区别是:@Autowired默认按类型装配,@Resource默认按名称装配,但是当找不到与名称匹配的bean时,才会按类型装配。
比如:我们用@Autowired为上面的代码UserDAO接口的实例对象进行注解,它会到Spring容器中去寻找与UserDAO对象相匹配的类型,如果找到该类型则将该类型注入到userdao字段中;
如果用@Resource进行依赖注入,它先会根据指定的name属性去Spring容器中寻找与该名称匹配的类型,例如:@Resource(name="userDao"),如果没有找到该名称,则会按照类型去寻找,找到之后,会对字段userDao进行注入。
通常我们使用@Resource。
使用注解注入依赖对象不用再在代码中写依赖对象的setter方法或者该类的构造方法,并且不用再配置文件中配置大量的依赖对象,使代码更加简洁,清晰,易于维护。
在Spring IOC编程的实际开发中推荐使用注解的方式进行依赖注入。
3、工厂方法注入
工厂方法注入又分为静态方法注入和非静态方法注入。这两者的区别主要是在装配bean对象的时候不一样,进而导致依赖注入的方法也不一样。
创建一个非静态工厂类:
1 package com.java1234.factory;
2
3 import com.java1234.entity.People;
4
5 /**
6 * 这是一个专门创建People对象的工厂,但是在这里为了简单起见,我们直接把创建的人的属性直接
7 * 固定好了。
8 * @author Baozi
9 *
10 */
11 public class PeopleFactory {
12 public People creatPeople() {
13 People people = new People();
14 people.setId(1000);
15 people.setName("小七");
16 people.setAge(22);
17 return people;
18 }
19 }
创建一个静态工厂类:
1 package com.java1234.factory;
2
3 import com.java1234.entity.People;
4
5 /**
6 * 这是一个专门创建People对象的工厂,但是在这里为了简单起见,我们直接把创建的人的属性直接
7 * 固定好了。
8 * @author Baozi
9 *
10 */
11 public class PeopleFactory_Static {
12 public static People creatPeople() {
13 People people = new People();
14 people.setId(1001);
15 people.setName("小狗");
16 people.setAge(29);
17 return people;
18 }
19 }
配置beans.xml文件:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans.xsd">
6
7 <!-- 工厂方法注入:javaBean对象的创建是通过一个专门的工厂来完成的,包括两种:静态工厂
8 和非静态工厂(静态在这里指的是创建javaBean的方法 是不是为静态的。)-->
9
10 <!-- 1、非静态的工厂方法注入:因为这个创建People的工厂是非静态的,所以我们还需要定义一
11 个Bean。这里大致的过程就相当于先创建一个工厂的Bean,为了让这个工厂创建一个people的
12 javaBean对象,我们需要待创建的JavaBean的id、由哪个工厂的哪个方法进行创建 -->
13 <bean id="peoplefactory" class="com.java1234.factory.PeopleFactory"></bean>
14 <bean id="people6" factory-bean="peoplefactory" factory-method="creatPeople"></bean>
15
16 <!-- 2、静态的工厂方法注入:静态的工厂方法注入就是指创建JavaBean对象的方法是static属
17 性的方法:这个我们在bean.xml文件中使用的时候一定要注意:静态方法的调用可以通过
18 ——类名.方法名——的方式获得。 -->
19 <bean id="people9" class="com.java1234.factory.PeopleFactory_Static" factory-method=creatPeople></bean>
20 </beans>
测试程序:
1 package com.java1234.Test;
2
3 import org.springframework.context.support.ClassPathXmlApplicationContext;
4
5 import com.java1234.entity.People;
6
7
8 public class Test {
9 public static void main(String[] args) {
10 @SuppressWarnings("resource")
11 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
12 //工厂方法的非静态方法创建JavaBean对象
13 People people6 = (People)applicationContext.getBean("people6");
14 System.out.println(people6);
15 //工厂方法的静态方法创建JavaBean对象
16 People people9 = (People)applicationContext.getBean("people9");
17 System.out.println(people9);
18 }
19 }
4、泛型依赖注入:这个设计的知识点比较多,等以后在总结。