天天看點

【我看Spring】IoC映射細節配置

       在上一篇文章《戲說Spring裡的【IoC與DI】》中已經把IoC容器和DI的應用概念很形象生動的解析了一遍。IoC這等控制關系在容器與被控元素之間的流轉,展現了一種設計的靈活性。我是在最近接觸到Spring架構的時候才意識到控制反轉這是一個非常有意思的概念、技術,囧。如圖,在Spring架構圖中,處于Core地位的就是IoC容器,也是Spring的精髓所在。

【我看Spring】IoC映射細節配置

       秉持手腦結合的方法政策,在頭腦中我們對IoC的認識一定要到位,将對象間及内部關系抽離出來統一管理,向Spring中這樣Everything  is  XML ,我們把關系分離出程式主體,也正符合J2EE的核心概念,并能夠使得各部件的重用性提高,系統擴充性增強。

       正是這樣,本着OO思想的一切事物皆對象,我們就能把需求中的各種顯隐資訊抽象出類,化為實際系統中能夠應用的對象,高度的應用抽象,又催生出了衆多的應用架構,各式各樣的抽象應用,使得開發更加友善快捷、簡單易用。試想,長此以往,今後的軟體開發又會簡化到何等程度呢?

       好的,現在還是需要在項目應用中去熟悉了解Sping架構中的核心概念。

       本篇先說,在Java Project中如何應用Spring架構中的IoC容器 去分離、管理關系。

      1、基礎環境搭配:

          a) 引入Spring核心包 spring.jar 以及其lib下的相關jar檔案 。

          b)引入Spring核心配置檔案applicationContext.xml

      2、在項目中建立基本類:    

Client.java /UserManager.java /UserManagerImpl.java /UserDao.java /UserDao4MySqlImpl.java
           

         a)其中UserManager和UserDao為接口,UserManagerImpl和UserDao4MySqlImpl.java分别為其接口實作

         b)基本的類的調用流程就是ClientàUserManagerImplàUserDao.

        不使用IoC容器則Client中代碼如下:

UserManager userManager = new UserManagerImpl(new UserDao4MySqlImpl());

       userManager.addUser("zhangsan_spring", "spring");

           

           可以看出,這裡邊的各類的調用關系是聯系很緊密的,同時代碼的複用性降低、靈活性降低。

        此時的Client也可以當做一個管理類關系的容器來看待。那麼在配置檔案中主要就是配置這裡的類間依賴調用關系。

      3、相關類代碼:

         ---------------  UserDao.java

package com.tgb.spring.dao;

public  interface  UserDao {

	public void addUser(String username,String password);
	
}
           

         --------------- UserDao4MySqlImpl.java

package com.tgb.spring.dao;

public class UserDao4MySqlImpl implements UserDao {

	@Override
	public void addUser(String username, String password) {
		
		System.out.println("UserDao4MySqlImpl.addUser()");
	}

}
           

          --------------- UserManager.java

package com.tgb.spring.manager;

public interface UserManager {
	
	public void addUser(String username,String password);
}
           

          --------------- UserManagerImpl.java

package com.tgb.spring.manager;

import com.tgb.spring.dao.UserDao;


public class UserManagerImpl implements UserManager {

	private UserDao userDao;
	
	public UserManagerImpl(){}
	
	//使用構造方法傳入userDao,就是避免UserManagerImpl知道我們會使用哪個具體的UserDao
	//這是一種封裝,反轉給spring的ioc容器.
	//主要是可以從applicationContext.xml配置中設定Bean标簽的屬性,
	//進而制定UserManagerImpl構造函數中的參數為何,這樣就進行了高度解耦,靈活性變強。
//	public UserManagerImpl(UserDao userDao) {
//		this.userDao = userDao;
//	}
//	
	

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void addUser(String username, String password) {
		
		//UserDao userDao = new UserDao4MySqlImpl();	//由我們的應用程式  負責    服務(對象)定位.
		userDao.addUser(username, password);
	}

}
           

         ---------------   Client.java

package com.tgb.spring.client;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.tgb.spring.manager.UserManager;

public class Client {
	
	public static void main(String[] args){		
		//由我們的應用程式負責服務(對象)定位
		//UserManager userManager = new UserManagerImpl(new UserDao4MySqlImpl());
		//userManager.addUser("zhangsan_spring", "spring");
		
		BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
		//這裡的getBean("userManager") 通過從applicationContext.xml檔案中讀取查找“userManager” 繼而生成一個執行個體并将其傳回
		UserManager userManager = (UserManager)factory.getBean("userManager");
		userManager.addUser("zhangsi", "password");		
	}
}
           

     4、applicationContext.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"
	     xmlns:aop="http://www.springframework.org/schema/aop"
	     xmlns:tx="http://www.springframework.org/schema/tx"
	     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

	<!-- 在IoC容器中注冊UserDao4MySqlImpl類 -->
	<bean id="userDao4MySql" class="com.tgb.spring.dao.UserDao4MySqlImpl"/>
		
	<!--在IoC容器中注冊UserManagerImpl類  -->
	<bean id = "userManager" class="com.tgb.spring.manager.UserManagerImpl">
		<!-- 相當于UserManagerImpl 中的構造函數 -->
		<!-- spring的Ioc容器會根據此進行對象建立 ,傳回給UserManagerImpl的構造方法中作為參數userDao-->
		<!--  <constructor-arg  ref="userDao4MySql"/>-->
		
		<!-- 這裡使用property 參數,是因為在UserManagerImpl中沒有 使用構造器方式,-->
		<!-- 而是使用了setUserDao() 的方式來做的。-->
		<property name="userDao" ref="userDao4MySql"/>
	</bean>
	
</beans>
           

     5、應用Spring架構IoC容器,就這樣把關系從UserDao4MySqlImpl和Client中抽離出來統一管理。使得系統更加容易配置、擴充,靈活性大大增強。

       在配置中的映射方式有三種,一種是上面代碼中涉及到的Setter()屬性方式和構造器方式,還有一種接口注入方式。上面就是Spring架構的基本應用,當然在項目中還會有更加複雜的邏輯管理要梳理,要厘清楚在Spring中IoC容器管理的一個内部執行順序。

       後面還會有關于AOP 切面程式設計的相關總結。