第一個案例已經是基于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