1. 程式人生 > >Spring02-註入和註解方式操作

Spring02-註入和註解方式操作

依賴 reference spa eas mime autowire span version scope

一. 依賴註入

測試類:Person.java

創建配置文件:applicationContext-injection.xml

創建測試代碼:InjectionTest.java

1. set方法註入

1.1 基本類型值註入使用value

配置:

1   <!-- value值為基本類型 -->
2   <bean name="person"  class="spring.bean.Person" >
3        <property name="name" value="jeck" />
4        <property name="age" value="11"/>
5
</bean>

測試代碼:

 1   @Test
 2   public  void  test1(){
 3         //TODO 測試基本數據類型註入數據
 4         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-injection.xml");
 5 
 6         Person person = context.getBean("person", Person.class);
 7 
 8         System.out.println("person = " + person);
9 //輸出結果:------------> Person.Person 10 // person = Person{name=‘jeck‘, age=11} 11 }

1.2 引入類型值註入ref

創建 Car.java:

 1 public class Car {
 2     private String name;
 3     private String color;
 4     
 5     public Car() {
 6         super();
 7         System.out.println("Car的空參構造方法");
8 } 9 //getter、setter、toString 10 }

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

1 public class Person {
2     private String name;
3     private Integer age;
4     private Car car;
5      //構造方法 getter setter toString方法 
6 }

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

 1   <bean name="person1" class="spring.bean.Person">
 2       <property name="name" value="helen"></property>
 3       <property name="age" value="18"></property>
 4       <property name="car" ref="car"></property>
 5   </bean>
 6     
 7   <bean name="car" class="spring.bean.Car">
 8       <property name="name" value="MINI"></property>
 9       <property name="color" value="灰色" ></property>
10   </bean>

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

2.構造函數註入

2.1 單個有參構造方法註入

在Person中創建有參構造函數:

1  public  Person(String  name , Car car){
2         this.name = name;
3         this.car = car;
4         System.out.println("Person的有參構造方法:"+name+car);
5  }

配置:

1 <bean name="person" class="spring.bean.Person">
2            <constructor-arg name="name" value="rose"/>
3            <constructor-arg name="car"  ref="car"/>
4  </bean>
5  <!-- 構造函數car時候引入 -->
6  <bean name="car"  class="spring.bean.Car" >
7            <property name="name" value="mime"/>
8            <property name="color" value="白色"/>
9  </bean>

測試:

 1   @Test
 2   public  void test2(){
 3         //TODO 測試參構造方法
 4         ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-injection.xml");
 5 
 6         Person person = context.getBean("person", Person.class);
 7 
 8         System.out.println(person);
 9         //結果:調用有參數構造方法,輸出
10   }

2.2. index屬性:按參數索引註入

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

例如以下兩個構造函數(第二個是新添加):

 1     public Person(String name, Car car) {
 2         super();
 3         System.out.println("Person(String name, Car car)");
 4         this.name = name;
 5         this.car = car;
 6     }  
 7     public Person(Car car, String name) {
 8         super();
 9         System.out.println("Person(Car car, String name)");
10         this.name = name;
11         this.car = car;
12     }

配置:使用 index 確定調用哪個構造函數

1     <bean name="person2" class="spring.bean.Person">
2         <constructor-arg name="name" value="helen" index="0"></constructor-arg>
3         <constructor-arg name="car" ref="car" index="1"></constructor-arg>
4     </bean>

測試:

重新執行第一步的測試用例,執行結果調用了第一個構造函數

2.3. type屬性:按參數類型註入

參數名和位置一致,但類型不一致時,使用type

例如以下兩個構造函數(第二個是新添加):

 1     public Person(Car car, String name) {
 2         super();
 3         System.out.println("Person(Car car, String name)");
 4         this.name = name;
 5         this.car = car;
 6     }
 7   
 8     public Person(Car car, Integer name) {
 9         super();
10         System.out.println("Person(Car car, Integer name)");
11         this.name = name + "";
12         this.car = car;
13     }

配置:使用type指定參數的類型

    <bean name="person2" class="spring.bean.Person">
        <constructor-arg name="name" value="988" type="java.lang.Integer"></constructor-arg>
        <constructor-arg name="car" ref="car" ></constructor-arg>
    </bean>

測試:

重新執行前面的測試用例,執行結果調用了第二個構造函數

3. p名稱空間註入

導入p名稱空間:

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

  • 基本類型值: p:屬性名="值"

  • 引入類型值: P:屬性名-ref="bean名稱"

配置:

 1 //1.第一步配置文件中 添加命名空間p 
 2  xmlns:p="http://www.springframework.org/schema/p"
 3 <beans xmlns="http://www.springframework.org/schema/beans"
 4        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5 xmlns:p="http://www.springframework.org/schema/p"      xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">
 6        //使用 p命稱空間進行賦值
 7         <bean name="person" class="spring.bean.Person"  p:name="人名" p:age="11"    p:car-ref="car">
 8        </bean>
 9        <bean name="car"  class="spring.bean.Car" >
10            <property name="name" value="mime" />
11            <property name="color" value="白色"/>
12        </bean>

測試:

1 @Test
2 public  void test2(){
3     //TODO 測試p命名空間註入
4     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-injection.xml");
5     Person person = context.getBean("person", Person.class);
6     System.out.println(person);
7     
8  }

4. spel註入

spring Expression Language:spring表達式語言

配置:

1   <bean name="car"  class="spring.bean.Car" >
2            <property name="name" value="mime" />
3            <property name="color" value="白色"/>
4   </bean>
5    <!--利用spel引入car的屬性 -->
6    <bean  name="person1"  class="spring.bean.Person"  p:car-ref="car">
7             <property name="name" value="#{car.name}"/>
8             <property name="age" value="#{person.age}"/>
9    </bean>

測試

1 @Test
2 public  void test3(){
3     //TODO 測試spel註入
4     ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-injection.xml");
5     Person person = context.getBean("person1", Person.class);
6     System.out.println(person);
7     
8  }

5. 復雜類型註入

創建配置文件:application-collection.xml

創建測試代碼:CollectionTest.java

創建測試實體類:TestCollection

創建TestCollection:

 1 /**
 2  * 練習:arr list map properties的註入
 3  */
 4 public class TestCollection {
 5 
 6     private Object [] arrs;
 7     private List<Object> list;
 8     private Map<String,Object> map;
 9     private Properties properties;
10 
11     public Object[] getArrs() {
12         return arrs;
13     }
14 
15     public void setArrs(Object[] arrs) {
16         this.arrs = arrs;
17     }
18 
19     public List<Object> getList() {
20         return list;
21     }
22 
23     public void setList(List<Object> list) {
24         this.list = list;
25     }
26 
27     public Map<String, Object> getMap() {
28         return map;
29     }
30 
31     public void setMap(Map<String, Object> map) {
32         this.map = map;
33     }
34 
35     public Properties getProperties() {
36         return properties;
37     }
38 
39     public void setProperties(Properties properties) {
40         this.properties = properties;
41     }
42 
43     @Override
44     public String toString() {
45         return "TestCollection{" +
46                 "arrs=" + Arrays.toString(arrs) +
47                 ", list=" + list +
48                 ", map=" + map +
49                 ", properties=" + properties +
50                 ‘}‘;
51     }
52 }

配置:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        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">
 4        <bean name="car" class="spring.bean.Car">
 5              <property name="name" value="保時捷"/>
 6              <property name="color" value="紅色" />
 7        </bean>
 8        <bean name="testColl" class="pring.bean.TestCollection">
 9            <!-- 數組變量註入 -->
10            <property name="arrs">
11                <list>
12                    <value>數組1</value>
13                    <!--引入其他類型-->
14                    <ref bean="car"/>
15                </list>
16            </property>
17            <!-- 集合變量賦值-->
18            <property name="list">
19                 <list>
20                     <value>集合1</value>
21                     <!--集合變量內部包含集合-->
22                     <list>
23                         <value>集合中的集合1</value>
24                         <value>集合中的集合2</value>
25                         <value>集合中的集合3</value>
26                     </list>
27                     <ref bean="car" />
28                 </list>
29            </property>
30 
31            <!--map賦值 -->
32            <property name="map">
33                <map>
34                    <entry key="car" value-ref="car" />
35                    <entry key="name" value="保時捷" />
36                    <entry key="age"  value="11"/>
37                </map>
38            </property>
39            <!-- properties賦值 -->
40            <property name="properties">
41                 <props>
42                     <prop key="name">pro1</prop>
43                     <prop key="age">111</prop>
44                 </props>
45            </property>
46        </bean>
47 
48 </beans>

測試:

1  @Test
2  public  void  test4(){
3         //TODO 復雜類型註入練習
4      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-collection.xml");
5      TestCollection textColl = context.getBean("testColl", TestCollection.class);
6      System.out.println("testColl = " + textColl);
7 
8    }

二.使用註解

使用註解的方式完成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

配置:

1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--較之前多了 xmlns:context -->
3 <beans xmlns="http://www.springframework.org/schema/beans"
4        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:context="http://www.springframework.org/schema/context"
5        xsi:schemaLocation="
6         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
7         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
8 </beans>

2.2 配置註解掃描

在applicationContext.xml中配置:

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

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!--較之前多了 xmlns:context -->
 3 <beans xmlns="http://www.springframework.org/schema/beans"
 4        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xmlns:context="http://www.springframework.org/schema/context"
 5        xsi:schemaLocation="
 6         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->        
 8      <!--掃描包設置-->
 9       <context:component-scan base-package="spring.bean">       </context:component-scan>
10 </beans>

2.3 使用註解

在Person類的頭部添加如下註解

 1 /**
 2   * @Component(person) == <bean name="person" class="spring.bean.Person" />
 3   */
 4 
 5 @Component("person")
 6 public class Person {
 7     private String name;
 8     private Integer age;
 9     private Car car;
10     public  Person(){
11         System.out.println("無參數構造方法!");
12     }
13   //getter,setter,toString
14 }  

測試:

1   @Test
2   public  void  test1(){
3      //TODO 測試註解入門
4      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
5      Person person = context.getBean("person", Person.class);
6      System.out.println("person = " + person);
7  }

3. 其他註解

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

3.1 類頭部可用的註解

1 @Service("person")         // service層
2 @Controller("person")     // controller層
3 @Repository("person")    // dao層

3.2 類頭部可用的註解

指定對象作用域

1 @Scope(scopeName="singleton")
2 @Scope(scopeName="prototype")

3.3 註入屬性value值

1.設置成員變量上:通過反射給變量賦值

1 @Value("name值")
2 private String name;

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

2.加在set方法上:通過set方法賦值

1 @Value("tom")
2 public void setName(String name)
3 {
4   this.name = name;
5 } 

3.4 自動裝配

  1. @Autowired

使用 @Autowired 自動裝配對象類型的屬性: 下面的Person中的Car使用了自動裝配

 1 //將Car定義成接口
 2 @Component
 3 public interface Car {
 4      void log();
 5 }
 6 //Baoma實現Car
 7 @Component
 8 public class Baoma implements Car {
 9     public void log() {
10         System.out.println("寶馬");
11     }
12 }
13 //XianDai實現Car
14 @Component
15 public class XianDai implements Car {
16     public void log() {
17         System.out.println("現代");
18     }
19 }

裝配類:

1 @Scope(scopeName = "prototype")
2 @Component("person")
3 public class Person {
4     @Value("name值")
5     private String name;
6     private Integer age;
7     @Autowired      
8     private Car car;  //自動裝配 可以選擇Car,如果Car是接口,找Car的實現類!

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

3.5 @Qualifier

  • 如果匹配多個類型一致的對象,將無法選擇具體註入哪一個對象

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

    1 @Scope(scopeName = "prototype")
    2 @Component("person")
    3 public class Person {
    4     @Value("name值")
    5     private String name;
    6     private Integer age;
    7     @Autowired  
    8     @Qualifier("baoma")   //指定實現類
    9     private Car car;  //自動裝配 可以選擇Car,如果Car是接口,找Car的實現類!

    3.6 @Resource

    @Resource 是java的註釋,但是Spring框架支持,@Resource指定註入哪個名稱的對象

    @Resource("name") == @Autowired + @Qualifier("name")

    1 @Resource(name="baoma") 
    2 private Car car;

    3.7 初始化和銷毀方法

    初始化和銷毀方法等同於配置文件添加的init-method和destroy-method功能,

    例:Person類中init方法和destroy方法添加如下註解:

    1  @PostConstruct
    2  public  void init(){
    3    System.out.println("初始化方法");
    4  }
    5  @PreDestroy
    6  public void destroy(){
    7    System.out.println("銷毀方法");
    8  }

    三. Spring整合JUnit測試

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

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

    spring-test-4.2.8.jar

    2、創建測試類

     1 //創建容器
     2 @RunWith(SpringJUnit4ClassRunner.class)
     3 //指定創建容器時使用哪個配置文件
     4 @ContextConfiguration("classpath:applicationContext.xml")
     5 public class RunWithTest {
     6     //將名為user的對象註入到u變量中
     7     @Resource(name="person")
     8     private Person p;
     9     @Test
    10     public void testCreatePerson(){
    11         System.out.println(p);
    12     }
    13 }

Spring02-註入和註解方式操作