Spring源碼學習(零) 動機

  學習Spring源碼的動機是一次偶然的單元測試, 以前對注入 ,控制反轉比較熟悉,先回顧一下當時測試 :java

目的:spring

 測試SpringMvc項目中的model層(俗稱Service層)  app

 如下的例子均採用註解注入模式,沒有在spring.xml中定義bean .框架

UserModel的代碼:工具

package com.younchen.model;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service("personModel")
public class PersonModel {

	
	@Autowired
	private Person person;
	
	public Person getPerson(){
		return person;
	}
	
	public void setPerson(Person person) {
		this.person = person;
	}
	
	public void showPersonName(){
		//
		System.out.println("姓名:"+person.getName());
	}
	
}

  userModel(  能夠理解爲userService ) ,該model中注入了person實體, 因此不能在測試類中以 UserModel userModel = new UserModel() 的方式進行 showPersonName()方法的測試  (推薦mockito 測試框架),  注入須要spring 框架的支持,不然報空指針異常,因而Spring 容器上下文ApplicationContext登場了.單元測試

SpringUtil類:學習

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringUtil {

		private static ApplicationContext context = null;
		
		public static ApplicationContext getApplicationContext() {
			if (context == null) {
				context = new ClassPathXmlApplicationContext("spring.xml");
			}
			return context;
		}

		public static ApplicationContext getApplicationContext(String path) {
			return new ClassPathXmlApplicationContext(path);
		}

		public static ApplicationContext getAnnotationConfigApplicationContext(String basePackages) {
			return new AnnotationConfigApplicationContext(basePackages);
		}
}

 

這個工具類的做用是返回Spring上下文的實例,這樣一來能夠經過上下文獲取spring中配置的bean對象 .測試

先看一下person類:this

package com.younchen.model;

import javax.inject.Named;

@Named("person")
public class Person {

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}


Person類中的@Name的做用與spring配置文件中定義<bean name="preson" class="com.younchen.model.person"> 的做用是同樣的,前提是spring.xml中定義包掃描器spa

<context:component-scan base-package="com.younchen.*" />


如今看一下測試類:

package com.younchen.test;

import com.younchen.model.PersonModel;
import com.younchen.util.SpringUtil;

public class ApplicationContext {

	public static void main(String[] args){
		//獲取application Context
	  PersonModel personModel =  (PersonModel) SpringUtil.getApplicationContext().getBean("personModel");
	  personModel.getPerson().setName("黑貓");
	  personModel.showPersonName();
	}
}


運行結果:

2014-7-8 16:08:46 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@b749757: startup date [Tue Jul 08 16:08:46 CST 2014]; root of context hierarchy
2014-7-8 16:08:46 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring.xml]
2014-7-8 16:08:46 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
姓名:黑貓

 

   依賴注入: 本例中的 Person 類, 不管是 在spring.xml中配置的方式,仍是用註解的方式,它都是由spring容器實例化的,不是人爲的去new 了一個對象。

   控制反轉: 本例中不明顯, 主程序只是負責調用模塊的方法而不去管這個模塊的具體實現,常常以工廠模式出現。

  依賴注入也是控制反轉的一種特殊形態,這裏舉個例子, 有些時候在userModel中注入的Person 能夠是Person的子類(這裏能夠參考一下 註解方式 同一個實體的不一樣註解方式 )而userModel的showPersonName方法無論Person的實例具體是哪一個類,只負責執行Person的getName方法.

  由此對Spring源碼產生了興趣(待續) 

相關文章
相關標籤/搜索