天天看點

Spring-IOC學習之兩種Spring注入方式的實作

一,什麼是Spring注入

Spring注入是指在啟動Spring容器加載bean配置的時候,完成對變量的指派行為。

二,Spring注入方式

Spring注入方式有兩種,第一種是設值注入(通過類提供的set()方法注值),第二種是構造注入(通過類提供的構造方法注值)。

三,工程搭建

由于本次是進行簡單的測試,是以隻用普通java項目進行測試,讀者為了友善導入jar包可自行建立maven工程。

項目目錄結構

Spring-IOC學習之兩種Spring注入方式的實作

InjectionDAO 

package com.injection.dao;

public interface InjectionDAO {

	/**
	 * 通路資料庫的操作
	 * 
	 * @param str
	 */
	public void save(String str);
}
           

InjectionDAOImpl

package com.injection.dao;

public class InjectionDAOImpl implements InjectionDAO {

	@Override
	public void save(String str) {
		System.out.println(str + "被存儲到資料庫...");
	}

}
           

InjectionService

package com.injection.service;

public interface InjectionService {

	/**
	 * 業務操作
	 * 
	 * @param str
	 */
	public void save(String str);
}
           

InjectionServiceImpl

package com.injection.service;

import com.injection.dao.InjectionDAO;

public class InjectionServiceImpl implements InjectionService {

	private InjectionDAO injectionDAO;

	/**
	 * 構造方法注入
	 * 
	 * @param injectionDAO
	 */
	public InjectionServiceImpl(InjectionDAO injectionDAO) {
		super();
		this.injectionDAO = injectionDAO;
	}

	/**
	 * setter() 方法注入
	 * 
	 * @param injectionDAO
	 */
	public void setInjectionDAO(InjectionDAO injectionDAO) {
		this.injectionDAO = injectionDAO;
	}

	@Override
	public void save(String str) {
		System.out.println("Service對" + str + "進行業務處理...");
		str = str + ":" + str.hashCode();
		injectionDAO.save(str);
	}

}
           

UnitTestBase

package com.injection.test;

import org.junit.After;
import org.junit.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.StringUtils;

public class UnitTestBase {

	private ClassPathXmlApplicationContext context;

	private String springXmlpath;// 就是配置spring的bean容器的路徑字元串,通過構造器獲得

	public UnitTestBase() {
	}

	public UnitTestBase(String springXmlpath) {
		this.springXmlpath = springXmlpath;
	}

	@Before
	public void before() {
		if (StringUtils.isEmpty(springXmlpath)) {
			/**
			 * classpath*是目前jar包目錄下的所有的jar包下進行的操作, 比如掃描等,classpath隻是目前單獨一個jar包裡的操作。比如在掃描器中,
			 * classpath隻掃描目前包裡的class,classpath*則掃描的是目前包目錄下所有的包裡的class.
			 */
			springXmlpath = "classpath*:spring-*.xml";
		}
		try {
			/**
			 * str.split(String regex)作用:根據正規表達式regex,将字元串str, 分割成字元串數組。"[,\\s]+"
			 * 是一個正規表達式,\\s表示各種空白符,+表示比對多個。
			 * StringUtils是org.apache.commons.lang下的一個用于操作Java.lang.String的工具類,
			 * 使用可能需要手工導入commons-lang-xx.jar 把SpringXmlpath路徑拆分開來,
			 * 因為springXmlpath路徑可能是多個路徑的拼接,拆分過之後每個路徑下的xml都會被掃描識别
			 */
			context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));
			context.start();// 通過掃描xml檔案擷取并啟動容器
		} catch (BeansException e) {
			e.printStackTrace();
		}
	}

	@After
	public void after() {
		context.destroy();
	}

	@SuppressWarnings("unchecked")
	protected <T extends Object> T getBean(String beanId) {
		try {
			/**
			 * T 這是泛型,在你不确定使用什麼類型參數的時候,泛型可以代表任意一種類型參數,比較靈活友善
			 */
			return (T) context.getBean(beanId);
		} catch (BeansException e) {
			e.printStackTrace();
			return null;
		}
	}

	protected <T extends Object> T getBean(Class<T> clazz) {
		try {
			return context.getBean(clazz);
		} catch (BeansException e) {
			e.printStackTrace();
			return null;
		}
	}

}
           

InjectionTest

package com.injection.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;

import com.injection.service.InjectionService;

@RunWith(BlockJUnit4ClassRunner.class)
public class InjectionTest extends UnitTestBase {

	public InjectionTest() {
		super("classpath:spring-injection.xml");
	}

	/**
	 * setter()方法注入測試
	 */
	@Test
	public void testSetter() {
		InjectionService service = super.getBean("injectionService");
		service.save("data");
	}
	/**
	 * constructor()方法注入測試
	 */
	@Test
	public void testConstructor() {
		InjectionService service = super.getBean("injectionService");
		service.save("data");
	}
}
           

spring-injection.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 id="injectionService" class="com.injection.service.InjectionServiceImpl">
		<property name="injectionDAO" ref="injectionDAO"></property>
	</bean>
	<!-- <bean id="injectionService" class="com.injection.service.InjectionServiceImpl"> 
		<constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg> 
		</bean> -->
	<bean id="injectionDAO" class="com.injection.dao.InjectionDAOImpl"></bean>

</beans>
           

四,代碼運作解釋

測試setter()方法注入:

在這之前一需要確定InjectionServiceImpl中編寫了對InjectionDAO對象的set設值方法,二需要確定spring-injection.xml中injectionService對injectionDAO的配置是

 <property name="injectionDAO" ref="injectionDAO"></property>這種方式。

把 <bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl"> 

        <constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg> 

        </bean>這一段代碼注釋掉

在InjectionTest類中右擊testSetter()方法運作,輸出結果如圖所示:

Spring-IOC學習之兩種Spring注入方式的實作

測試構造方法注入:

在這之前一需要確定InjectionServiceImpl中編寫構造方法對InjectionDAO對象設值,二需要確定spring-injection.xml中injectionService對injectionDAO的配置是

 <constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>這種方式。

把   <bean id="injectionService" class="com.injection.service.InjectionServiceImpl">

        <property name="injectionDAO" ref="injectionDAO"></property>

    </bean>這一段代碼注釋掉

在InjectionTest類中右擊testConstructor()方法運作,輸出結果如圖所示:

Spring-IOC學習之兩種Spring注入方式的實作