在应用中,我们常常使用<ref>标签为JavaBean注入它依赖的对象。但是对于一个大型的系统,这个操作将会耗费我们大量的资源,我们不得不花费大量的时间和精力用于创建和维护系统中的<ref>标签。实际上,这种方式也会在另一种形式上增加了应用程序的复杂性,那么如何解决这个问题呢?Spring为我们提供了一个自动装配的机制,尽管这种机制不是很完善,但是在应用中结合<ref>标签还是可以大大的减少我们的劳动强度。前面提到过,在定义Bean时,<bean>标签有一个autowire属性,我们可以通过指定它来让容器为受管JavaBean自动注入依赖对象。
<bean>的autowire属性有如下六个取值,他们的说明如下:
1、 No:即不启用自动装配。Autowire默认的值。
2、 byName:通过属性的名字的方式查找JavaBean依赖的对象并为其注入。比如说类Computer有个属性printer,指定其autowire属性为byName后,Spring IoC容器会在配置文件中查找id/name属性为printer的bean,然后使用Seter方法为其注入。
3、 byType:通过属性的类型查找JavaBean依赖的对象并为其注入。比如类Computer有个属性printer,类型为Printer,那么,指定其autowire属性为byType后,Spring IoC容器会查找Class属性为Printer的bean,使用Seter方法为其注入。
4、 constructor:通byType一样,也是通过类型查找依赖对象。与byType的区别在于它不是使用Seter方法注入,而是使用构造子注入。
5、 autodetect:在byType和constructor之间自动的选择注入方式。
6、 default:由上级标签<beans>的default-autowire属性确定。
注意:在配置bean时,<bean>标签中Autowire属性的优先级比其上级标签高,即是说,如果在上级标签中定义default-autowire属性为byName,而在<bean>中定义为byType时,Spring IoC容器会优先使用<bean>标签的配置。
下面通过一个综合示例来说明这一点
User.java
1. <span style="font-size: medium;">package
2.
3.
4. public class
5. private
6. private
7. private
8. public
9. return
10. }
11. public void
12. this.id = id;
13. }
14. public
15. return
16. }
17. public void
18. this.username = username;
19. }
20. public
21. return
22. }
23. public void
24. this.pwd = pwd;
25. }
26.
27.
28. }
29. </span>
UserDao.java
1. <span style="font-size: medium;">package
2.
3. import
4.
5. import
6.
7.
8. public interface
9. void
10. void
11. void
12. User findById(Serializable id);
13. }</span><span style="font-size: medium;">
14. </span>
UserDaoHibernateImpl.java
1. <span style="font-size: medium;">package
2.
3. import
4.
5. import
6.
7. public class UserDaoHibernateImpl implements
8.
9. @Override
10. public void
11. "UserDaoHibernateImpl:add方法");
12. }
13.
14.
15. @Override
16. public void
17. "UserDaoHibernateImpl:delete方法");
18.
19. }
20.
21. @Override
22. public
23. "UserDaoHibernateImpl:findById方法");
24. return null;
25. }
26.
27. @Override
28. public void
29. "UserDaoHibernateImpl:update方法");
30.
31. }
32.
33. }
34. </span>
UserDaoJDBCImpl.java
1. <span style="font-size: medium;">package
2.
3. import
4.
5. import
6.
7.
8. public class UserDaoJDBCImpl implements
9.
10. @Override
11. public void
12. "UserDaoJDBCImpl==add方法");
13.
14. }
15.
16. @Override
17. public void
18. "UserDaoJDBCImpl==delete方法");
19.
20. }
21.
22. @Override
23. public
24. "UserDaoJDBCImpl==findById方法");
25. return null;
26. }
27.
28.
29. @Override
30. public void
31. "UserDaoJDBCImpl==update方法");
32.
33. }
34.
35. }
36. </span>
ServiceFacade.java
1. <span style="font-size: medium;">package
2.
3. import
4. import
5.
6.
7. public class
8.
9. //依赖的对象:主动去获取
10. private
11.
12. public
13.
14. //构造器
15. public
16. this.userDao = userDao;
17.
18. "调用带UserDao参数的构造方法");
19. }
20.
21. //set方法
22. public void
23. this.userDao = userDao;
24. }
25.
26.
27. public void
28. userDao.add(user);
29. }
30.
31. public
32. return
33. }
34. }
35. </span>
Spring配置applicationContext.xml
1. <span style="font-size: medium;"><?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. xmlns:aop="http://www.springframework.org/schema/aop"
5. xmlns:tx="http://www.springframework.org/schema/tx"
6. xsi:schemaLocation="
7. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
8. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
9. >
10.
11. <!-- <bean id="userDao" class="com.javacrazyer.dao.UserDaoHibernateImpl"/>-->
12. <bean id="userDao" class="com.javacrazyer.dao.UserDaoJDBCImpl"/>
13. <!--自动装配 -->
14. <bean id="sf" class="com.javacrazyer.service.ServiceFacade" autowire="autodetect" />
15.
16. <!-- <bean id="sf" class="com.javacrazyer.service.ServiceFacade" >-->
17. <!-- <property name="userDao" ref="userDao"/>-->
18. <!-- </bean>-->
19. </beans>
20. </span>
测试类
1. <span style="font-size: medium;">package
2.
3. import
4. import
5. import
6.
7. import
8. import
9.
10.
11. public class
12.
13. @Test
14. public void
15.
16. //从Spring的Bean容器中获取想要的实例
17. //BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
18. //ServiceFacade sf = (ServiceFacade)factory.getBean("sf");
19.
20. new ClassPathXmlApplicationContext("applicationContext.xml");
21. "sf");
22.
23. new
24. }
25. }
26. </span>
结果是
UserDaoJDBCImpl==add方法
如果将bean的id为UserDao的换成hibernate实现方式,那么结果就会是
UserDaoHibernateImpl==add方法
所以,在自动装配中无需像这样
<bean id="sf" class="com.javacrazyer.service.ServiceFacade" >
<property name="userDao" ref="userDao"/>
</bean>
配置引用注入对象
总结:
自动装配并不是十全十美的,我们不论是使用byName还是byType的方法,Spring不一定就能很准确的为我们找到JavaBean依赖的对象。另外,如果使用自动装配,Spring配置文件的可读性也大大降低,我们不能很容易的看出个bean之间的依赖关系,这也在一定程度上降低了程序可维护性。因此在使用自动装配时,应当权衡利弊,合理的与ref的方法相结合,尽量在降低工作量的同时,保证应用的可维护度。