第一个案例已经是基于XML配置spring的工厂了,那么现在,正了八景的配置一下。
MVC 的三层式结构已经深入人心了,但是在此不得不稍微吐槽一下,虽然层次清晰,但是还是有不少开发者,甚至一些站点,将这些层次混淆,在本来单单是界面层的页 面中,或者是控制器中嵌入了大量的业务代码,而业务层和数据层却干干净净,就是定义了单纯接口加对应实现。更有甚者在DAO中取request...你要这么写还分毛线层啊...线层啊...层啊!咳咳...言归正传,定义好演示用的数据层和业务层的接口和实现类
DaoInterface
1 package org.duyt.dao;
2 public interface IUserDao {
3 public void add();
4 }
DaoImpl
1 package org.duyt.dao.impl;
2 import org.duyt.dao.IUserDao;
3 public class UserDao implements IUserDao {
4 public void add() {
5 System.out.println("用户增加方法");
6 }
7 }
ServiceInterface
1 package org.duyt.service;
2 public interface IUserService {
3 public void add();
4 }
5
ServiceImpl
1 package org.duyt.service.impl;
2 import org.duyt.dao.IUserDao;
3 import org.duyt.service.IUserService;
4 public class UserService implements IUserService {
5 private IUserDao userDao;
6 public void add() {
7 userDao.add();
8 }
9 public IUserDao getUserDao() {
10 return userDao;
11 }
12 public void setUserDao(IUserDao userDao) {
13 this.userDao = userDao;
14 }
15 }
实体类
1 package org.duyt.domain;
2 import java.util.List;
3 import java.util.Map;
4 public class User {
5 private int id;
6 private String name;
7 private Map<Object, Object> mapTest;
8 private List<Object> listTest;
9 public User() {
10 }
11 public User(int id, String name) {
12 this.id = id;
13 this.name = name;
14 }
15 //get/set略
15 }
16
Action
1 package org.duyt.action;
2 import org.duyt.domain.User;
3 import org.duyt.service.IUserService;
4 public class UserAction {
5 private IUserService userService;
6 private String testStringA;
7 private String testStringB;
8 private User user;
9 public UserAction(String testStringA,String testStringB) {
10 this.testStringA = testStringA;
11 this.testStringB = testStringB;
12 }
13 public UserAction() {
14 }
15 //get/set略
16 }
17
1 package org.duyt.action;
2 import org.duyt.service.IUserService;
3 public class AutowiredAction {
4 private IUserService userService;
5 public void add(){
6 userService.add();
7 }
8 //get/set略
9 }
10
重点是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-3.0.xsd" >
6 <!-- default-autowire="byName" 此处可以设置全局的自动注入,开启之后所有bean内的属性都会自动按名称注入-->
7
8 <!-- scope表示一个对象的有效范围,singleton表示单例,prototype表示原型,也就是多例,每次都会获取一个新的实例。
9 单例和原型是最常用的方式,spring还提供了以request和session为使用范围的控制,是否使用见仁见智。-->
10
11 <!-- 有效范围的选择需要根据bean的用途来决定,比如Action实例就需要选择prototype,如果使用单例去获取Action实例
12 那么Action的属性可能会影响前后的请求,对象实例的状态会影响其本身的功能,那么就需要使用原型去获取对象的实例;而service
13 和Dao的实例就无须担心,直接使用单例获取实例即可,不会因为自身的属性状态而影响功能的实现,因为他们本身不存在状态。默认情况下
14 会使用单例进行对象实例的创建。 -->
15 <bean id="userAction" class="org.duyt.action.UserAction" scope="prototype">
16 <!-- property是指定要注入的属性,通过属性的set方法进行注入,ref则是对bean的引用-->
17 <property name="userService" ref="userService"/>
18 <property name="user" ref="user"/>
19
20 <!-- 通过构造方法进行属性的注入,前提是要有只含有下述两个参数的构造方法,还要有空构造 -->
21 <constructor-arg name="testStringA" value="测试用字符串AAA"/>
22 <constructor-arg name="testStringB" value="测试用字符串BBB"/>
23 </bean>
24
25 <!-- 一般属性的注入和集合对象属性的注入-->
26 <bean id="user" class="org.duyt.domain.User" scope="prototype">
27 <property name="id" value="1"/>
28 <property name="name" value="duyt"/>
29 <!-- 注入map -->
30 <property name="mapTest">
31 <map>
32 <entry key="1" value="nihao"/>
33 <entry key="2" value="hello"/>
34 </map>
35 </property>
36 <!-- 注入list -->
37 <property name="listTest">
38 <list>
39 <value>1</value>
40 <value>2</value>
41 <value>3</value>
42 </list>
43 </property>
44 </bean>
45
46 <!-- 此处设置了autowire = byName属性,会根据成员变量的名称自动搜索对应的bean并注入,这是推荐的方式,因为bean的名字是不应该重复的,
47 只要属性的名称能够匹配到bean的id,并且属性含有get/set,那么就会成功注入。还有一种方式是按照类型注入byType,按照类型注入可能会存在一个接口
48 有多个实现类的情况,比如action的XXXservice接口有多个实现类,那么注入的时候会产生异常 -->
49 <bean id="autowiredAction" class="org.duyt.action.AutowiredAction" scope="prototype" autowire="byName"/>
50
51 <bean id="userDao" class="org.duyt.dao.impl.UserDao" scope="singleton"/>
52 <bean id="userService" class="org.duyt.service.impl.UserService" scope="singleton">
53 <property name="userDao" ref="userDao"/>
54 </bean>
55
56 </beans>
最后使用测试类来验证注入的情况
1 package org.duyt.test;
2
3 import org.duyt.action.AutowiredAction;
4 import org.duyt.action.UserAction;
5 import org.junit.Test;
6 import org.springframework.beans.factory.BeanFactory;
7 import org.springframework.context.support.ClassPathXmlApplicationContext;
8
9 public class IocTest {
10
11 private BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");
12
13 @Test
14 public void test(){
15 UserAction ua = (UserAction) factory.getBean("userAction");
16 //测试使用构造方法进行注入
17 System.out.println(ua.getTestStringA());
18 System.out.println(ua.getTestStringB());
19 //属性注入
20 System.out.println(ua.getUser().getId());
21 System.out.println(ua.getUser().getName());
22 //集合注入
23 System.out.println(ua.getUser().getListTest().size());
24 System.out.println(ua.getUser().getMapTest().get("1"));
25 //根据属性名自动注入
26 AutowiredAction aa = (AutowiredAction) factory.getBean("autowiredAction");
27 aa.add();
28 }
29
30 }
31