Spring 使用介紹(八)—— 零配置
阿新 • • 發佈:2018-05-09
大於 pat UC HA 使用 普通 lang 概述 ns-3
一、概述
所謂零配置,並不是說一點配置都沒有了,而是配置很少而已。通過約定來減少需要配置的數量,提高開發效率。
零配置實現主要有以下兩種方式:
- 慣例優先原則:也稱為約定大於配置(convention over configuration),即通過約定代碼結構或命名規範來減少配置數量,同樣不會減少配置文件;即通過約定好默認規範來提高開發效率。
- 基於註解的規約配置:通過在指定類上指定註解,通過註解約定其含義來減少配置數量,從而提高開發效率;如事務註解@Transaction是不是基於註解的規約,只有在指定的類或方法上使用該註解就表示其需要事務。
Spring基於註解的規約配置有三個層級:
- Bean
- Bean定義:通過註解方式進行Bean配置元數據定義,從而完全將Bean配置元數據從配置文件中移除。
- Java類替換配置文件:使用Java類來定義所有的Spring配置,完全消除XML配置文件
二、Bean依賴註入
1、開啟註解支持
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:annotation-config /> </beans>
2、@Autowired註解
@Autowired可用於字段、構造器、方法的註入,提供required設置字段註入是否必須,默認為必須
public @interface Autowired { boolean required() default true; }
實例如下:
實體類:
public class TestBean { // for: 構造器註入 private String message1; // for: 字段註入 @Autowired private String message2; // for: 靜態字段不能註入 @Autowired private static String message3; // for: 方法註入 private String message4; // for: 泛型註入 @Autowired private List<String> messages; // for: 泛型註入(指定具體類型) @Autowired private ArrayList<String> messages2; @Autowired private TestBean(String msg) { this.message1 = msg; } public String getMessage1() { return message1; } public String getMessage2() { return message2; } public String getMessage3() { return message3; } public String getMessage4() { return message4; } @Autowired public void setMessage4(String message4) { this.message4 = message4; } public List<String> getMessages() { return messages; } public List<String> getMessages2() { return messages2; } }
XML配置
<bean class="java.util.ArrayList"> <constructor-arg index="0"> <list value-type="java.lang.String"> <value>matt</value> <value>pretty</value> </list> </constructor-arg> </bean> <bean id="str" class="java.lang.String"> <constructor-arg index="0" value="kevin"/> </bean> <bean class="cn.matt.noconfig.TestBean"></bean>
測試
@org.junit.Test public void testAutowired() { ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml"); TestBean testBean = context.getBean(TestBean.class); System.out.println("構造器註入:" + testBean.getMessage1()); System.out.println("字段註入:" + testBean.getMessage2()); System.out.println("靜態字段不能註入:" + testBean.getMessage3()); System.out.println("方法註入:" + testBean.getMessage4()); System.out.println("泛型註入:" + testBean.getMessages()); System.out.println("泛型註入(指定具體類型):" + testBean.getMessages2()); } /*輸出: 構造器註入:kevin 字段註入:kevin 靜態字段不能註入:null 方法註入:kevin 泛型註入:[kevin] 泛型註入(指定具體類型):[matt, pretty] */
註意,@Autowired不支持靜態字段註入;對於泛型的註入,須明確指定泛型的具體類型
數組、集合、字典類型的根據類型自動裝配和普通類型的自動裝配是有區別的:
- 數組類型、集合(Set、Collection、List)接口類型:將根據泛型獲取匹配的所有候選者並註入到數組或集合中,如“List<HelloApi> list”將選擇所有的HelloApi類型Bean並註入到list中,而對於集合的具體類型將只選擇一個候選者,“如 ArrayList<HelloApi> list”將選擇一個類型為ArrayList的Bean註入,而不是選擇所有的HelloApi類型Bean進行註入;
- 字典(Map)接口類型:同樣根據泛型信息註入,鍵必須為String類型的Bean名字,值根據泛型信息獲取,如“Map<String, HelloApi> map” 將選擇所有的HelloApi類型Bean並註入到map中,而對於具體字典類型如“HashMap<String, HelloApi> map”將只選擇類型為HashMap的Bean註入,而不是選擇所有的HelloApi類型Bean進行註入。
2、@Value註解
@Value註解用於註入SpEL表達式,可放置在字段、@Autowired註解的方法的參數上
實例如下:
實體類:
public class TestBean2 { @Value("#{str}") private String message1; private String message2; public String getMessage1() { return this.message1; } public String getMessage2() { return message2; } @Autowired public void setMessage2(@Value("#{str}#{str}") String message2) { this.message2 = message2; } }
XML配置:
<bean id="str" class="java.lang.String"> <constructor-arg index="0" value="kevin"/> </bean> <bean class="cn.matt.noconfig.TestBean2"></bean>
測試:
@org.junit.Test public void testValue() { ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml"); TestBean2 testBean = context.getBean(TestBean2.class); Assert.assertTrue(StringUtils.equals("kevin", testBean.getMessage1())); Assert.assertTrue(StringUtils.equals("kevinkevin", testBean.getMessage2())); }
3、
Spring 使用介紹(八)—— 零配置