Springソース学習(ゼロ)動機

3880 ワード

Springソースコードを学ぶ動機は偶然のユニットテストで、前に注入、制御反転に詳しいので、まず当時のテストを振り返ってみましょう.
目的:
SpringMvcプロジェクトのモデル層(通称サービス層)のテスト
以下の例はいずれも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と理解できる)は、このモデルに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類を見てみましょう.
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プロファイルで定義されているの役割と同じで、spring.xmlでパケットスキャナを定義する
<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
 : 

 
依存注入:spring.xmlで構成されている方法も、注釈で構成されている方法も、springコンテナによってインスタンス化されており、人為的にnewを除去したオブジェクトではありません.
制御反転:この例では明らかではなく、メインプログラムはモジュールを呼び出す方法を担当するだけで、このモジュールの具体的な実現を管理せず、工場モードでよく現れる.
依存注入も制御反転の特殊な形態であるが、ここでは例を挙げる、userModelに注入するPersonはPersonのサブクラス(ここでは注釈方式が同じエンティティの異なる注釈方式を参照することができる)であり、userModelのshowPersonName方式はPersonのインスタンスが具体的にどのクラスであるかにかかわらず、PersonのgetName法のみを実行する.
これによりSpringソースに興味を持つようになった(続き)