Spring-注入和註解方式操作02

今天任務

1。 依賴注入詳解2。 使用註解的方式實現依賴注入3。 Spring中使用JUnit測試

一. 依賴注入

測試類:Person。java

建立配置檔案:applicationContext-injection。xml

建立測試程式碼:InjectionTest。java

1. set方法注入

1.1 基本型別值注入使用value

配置:

<!—— value值為基本型別 ——>

測試程式碼:

@Test public void test1(){ //TODO 測試基本資料型別注入資料 ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext-injection。xml”); Person person = context。getBean(“person”, Person。class); System。out。println(“person = ” + person); //輸出結果:——————> Person。Person // person = Person{name=‘jeck’, age=11} }

1.2 引入型別值注入ref

建立 Car。java:

public class Car { private String name; private String color; public Car() { super(); System。out。println(“Car的空參構造方法”); } //getter、setter、toString}

修改Person。java,在Person中引入Car:

public class Person { private String name; private Integer age; private Car car; //構造方法 getter setter toString方法 }

配置:利用ref屬性給 person的car屬性賦值

測試: 使用之前測試用例即可!

2.建構函式注入

2.1 單個有參構造方法注入

在Person中建立有參建構函式:

public Person(String name , Car car){ this。name = name; this。car = car; System。out。println(“Person的有參構造方法:”+name+car); }

配置:

<!—— 建構函式car時候引入 ——>

測試:

@Test public void test2(){ //TODO 測試參構造方法 ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext-injection。xml”); Person person = context。getBean(“person”, Person。class); System。out。println(person); //結果:呼叫有引數構造方法,輸出 }

2.2. index屬性:按引數索引注入

引數名一致,但位置不一致時,使用 index

例如以下兩個建構函式(第二個是新新增):

public Person(String name, Car car) { super(); System。out。println(“Person(String name, Car car)”); this。name = name; this。car = car; } public Person(Car car, String name) { super(); System。out。println(“Person(Car car, String name)”); this。name = name; this。car = car; }

配置:使用 index 確定呼叫哪個建構函式

測試:

重新執行第一步的測試用例,執行結果呼叫了第一個建構函式

2.3. type屬性:按引數型別注入

引數名和位置一致,但型別不一致時,使用type

例如以下兩個建構函式(第二個是新新增):

public Person(Car car, String name) { super(); System。out。println(“Person(Car car, String name)”); this。name = name; this。car = car; } public Person(Car car, Integer name) { super(); System。out。println(“Person(Car car, Integer name)”); this。name = name + “”; this。car = car; }

配置:使用type指定引數的型別

測試:

重新執行前面的測試用例,執行結果呼叫了第二個建構函式

3. p名稱空間注入

匯入p名稱空間:

使用p:屬性名 完成注入,走set方法

基本型別值: p:屬性名=“值”

引入型別值: P:屬性名-ref=“bean名稱”

配置:

//1。第一步配置檔案中 新增名稱空間p xmlns:p=“http://www。springframework。org/schema/p” //使用 p命稱空間進行賦值

測試:

@Testpublic void test2(){ //TODO 測試p名稱空間注入 ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext-injection。xml”); Person person = context。getBean(“person”, Person。class); System。out。println(person); }

4. spel注入

spring Expression Language:spring表示式語言

配置:

<!——利用spel引入car的屬性 ——>

測試

@Testpublic void test3(){ //TODO 測試spel注入 ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext-injection。xml”); Person person = context。getBean(“person1”, Person。class); System。out。println(person); }

5. 複雜型別注入

建立配置檔案:application-collection。xml

建立測試程式碼:CollectionTest。java

建立測試實體類:TestCollection

建立TestCollection:

/** * 練習:arr list map properties的注入 */public class TestCollection { private Object [] arrs; private List list; private Map map; private Properties properties; public Object[] getArrs() { return arrs; } public void setArrs(Object[] arrs) { this。arrs = arrs; } public List getList() { return list; } public void setList(List list) { this。list = list; } public Map getMap() { return map; } public void setMap(Map map) { this。map = map; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this。properties = properties; } @Override public String toString() { return “TestCollection{” + “arrs=” + Arrays。toString(arrs) + “, list=” + list + “, map=” + map + “, properties=” + properties + ‘}’; }}

配置:

<?xml version=“1。0” encoding=“UTF-8”?> <!—— 陣列變數注入 ——> 陣列1 <!——引入其他型別——> <!—— 集合變數賦值——> 集合1 <!——集合變數內部包含集合——> 集合中的集合1 集合中的集合2 集合中的集合3 <!——map賦值 ——> <!—— properties賦值 ——> pro1 111

測試:

@Test public void test4(){ //TODO 複雜型別注入練習 ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext-collection。xml”); TestCollection textColl = context。getBean(“testColl”, TestCollection。class); System。out。println(“testColl = ” + textColl); }

二.使用註解

使用註解的方式完成IOC

1. 準備工作

建立專案: spring-02-annotation

匯入jar包: spring-core,spring-context,spring-suppot-context,spring-beans,spring-expression, log4j,commons-logging,本次多加一個:spring-aop

引入日誌配置檔案:log4j。properties

實體類: 原專案 Person。java 和 Car。java即可

建立配置檔案: applicationContext。xml

建立測試程式碼類:AnnotationTest。java

2. 使用註解

2.1 引入Context的約束

​ 參考檔案位置:spring-framework-4。2。4。RELEASE\docs\spring-framework-reference\html\xsd-configuration。html 40。2。8 the context schema

配置:

<?xml version=“1。0” encoding=“UTF-8”?><!——較之前多了 xmlns:context ——> <!—— bean definitions here ——>

2.2 配置註解掃描

在applicationContext。xml中配置:

指定掃描 包 下所有類中的註解,掃描包時,會掃描包所有的子孫包。

<?xml version=“1。0” encoding=“UTF-8”?><!——較之前多了 xmlns:context ——> <!—— bean definitions here ——> <!——掃描包設定——>

2.3 使用註解

在Person類的頭部新增如下註解

/** * @Component(person) == */@Component(“person”)public class Person { private String name; private Integer age; private Car car; public Person(){ System。out。println(“無引數構造方法!”); } //getter,setter,toString}

測試:

@Test public void test1(){ //TODO 測試註解入門 ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext。xml”); Person person = context。getBean(“person”, Person。class); System。out。println(“person = ” + person); }

3. 其他註解

介紹其他常用註解,測試方式同前

3.1 類頭部可用的註解

@Service(“person”) // service層@Controller(“person”) // controller層@Repository(“person”) // dao層

3.2 類頭部可用的註解

指定物件作用域

@Scope(scopeName=“singleton”)@Scope(scopeName=“prototype”)

3.3 注入屬性value值

1。設定成員變數上:透過反射給變數賦值

@Value(“name值”)private String name;

@Value("name值") 等同於 @Value(value="name值")

2。加在set方法上:透過set方法賦值

@Value(“tom”)public void setName(String name){ this。name = name;}

3.4 自動裝配

@Autowired

使用 @Autowired 自動裝配物件型別的屬性: 下面的Person中的Car使用了自動裝配

//將Car定義成介面@Componentpublic interface Car { void log();}//Baoma實現Car@Componentpublic class Baoma implements Car { public void log() { System。out。println(“寶馬”); }}//XianDai實現Car@Componentpublic class XianDai implements Car { public void log() { System。out。println(“現代”); }}

裝配類:

@Scope(scopeName = “prototype”)@Component(“person”)public class Person { @Value(“name值”) private String name; private Integer age; @Autowired private Car car; //自動裝配 可以選擇Car,如果Car是介面,找Car的實現類!

注意:

以上操作會出現一個問題,如果Car是介面,且Car只有一個實現類,那麼@Autowired會自動將實現類裝配給Person的car變數上,但是如果Car是介面,並且有兩個以上實現類,那麼自動裝配就會報錯,無法選擇由哪個實現類賦值。所以需要配合另一個註釋@Qualifier(“bean name”), 這個屬性可以將@Autowired按型別賦值改成按bean名字賦值。

3.5 @Qualifier

如果匹配多個型別一致的物件,將無法選擇具體注入哪一個物件

使用@Qualifier()註解告訴spring容器自動裝配哪個名稱的物件。

@Scope(scopeName = “prototype”)@Component(“person”)public class Person { @Value(“name值”) private String name; private Integer age; @Autowired @Qualifier(“baoma”) //指定實現類 private Car car; //自動裝配 可以選擇Car,如果Car是介面,找Car的實現類!

3.6 @Resource

@Resource 是java的註釋,但是Spring框架支援,@Resource指定注入哪個名稱的物件

@Resource(“name”) == @Autowired + @Qualifier(“name”)

@Resource(“baoma”) private Car car;

3.7 初始化和銷燬方法

初始化和銷燬方法等同於配置檔案新增的init-method和destroy-method功能,

例:Person類中init方法和destroy方法新增如下註解:

@PostConstruct public void init(){ System。out。println(“初始化方法”); } @PreDestroy public void destroy(){ System。out。println(“銷燬方法”); }

三. Spring整合JUnit測試

spring整合junit,為我們提供了方便的測試方式

1、導包:在spring-02-annotation專案中再加入如下包

spring-test-4。2。8。jar

2、建立測試類

//建立容器@RunWith(SpringJUnit4ClassRunner。class)//指定建立容器時使用哪個配置檔案@ContextConfiguration(“classpath:applicationContext。xml”)public class RunWithTest { //將名為user的物件注入到u變數中 @Resource(name=“person”) private Person p; @Test public void testCreatePerson(){ System。out。println(p); }}

Spring-注入和註解方式操作02