Spring 自動裝配及其註解

一.屬性自動裝配

 首先,準備三個類,分別是User,Cat,Dog。其中User屬性擁有Cat和Dog對象。

複製代碼

 1 package com.hdu.autowire;
 2 
 3 public class User {
 4     private Cat cat;
 5     private Dog dog;
 6     private String str;
 7     
 8     public Cat getCat() {
 9         return cat;
10     }
11     public void setCat(Cat cat) {
12         this.cat = cat;
13     }
14     public Dog getDog() {
15         return dog;
16     }
17     public void setDog(Dog dog) {
18         this.dog = dog;
19     }
20     public String getStr() {
21         return str;
22     }
23     public void setStr(String str) {
24         this.str = str;
25     }
26 }

複製代碼

複製代碼

1 package com.hdu.autowire;
2 
3 public class Cat {
4     public void shout() {
5         System.out.println("miao~");
6     }
7 }

複製代碼

複製代碼

1 package com.hdu.autowire;
2 
3 public class Dog {
4     public void shout() {
5         System.out.println("wang~");
6     }
7 }

複製代碼

 測試代碼:

複製代碼

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 public class TestIOCDI {
 8     @Test
 9     public void testMethodAutowire() {
10         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_autowire.xml");
11         com.hdu.autowire.User user = context.getBean("user", com.hdu.autowire.User.class);
12         user.getCat().shout();
13         user.getDog().shout();
14     }
15 }

複製代碼

    1.1 xml配置文件

複製代碼

<bean id="cat" class="com.hdu.autowire.Cat"></bean>
<bean id="dog" class="com.hdu.autowire.Dog"></bean>
    
<bean id="user" 
          class="com.hdu.autowire.User">
    <property name="cat" ref="cat"></property>
    <property name="dog" ref="dog"></property>
    <property name="str" value="haha"></property>
</bean>

複製代碼

 

    1.2 autowire byName (按名稱自動裝配)

        由於在手動配置xml過程中,常常發生字母缺漏和大小寫等錯誤,而無法對其進行檢查,使得開發效率降低。採用自動裝配將避免這些錯誤,並且使配置簡單化。

  當一個bean節點帶有 autowire byName的屬性時。

    ①將查找其類中所有的set方法名,例如setCat,獲得將set去掉並且首字母小寫的字符串,即cat。

    ②去spring容器中尋找是否有此字符串名稱id的對象。

    ③如果有,就取出注入;如果沒有,就報空指針異常。

複製代碼

<bean id="cat" class="com.hdu.autowire.Cat"></bean>
<bean id="dog" class="com.hdu.autowire.Dog"></bean>
    
<bean id="user" 
      class="com.hdu.autowire.User"
      autowire="byName">
</bean>

複製代碼

        如果將 <bean id="cat" class="com.hdu.autowire.Cat"></bean> 改成

<bean id="catXXX" class="com.hdu.autowire.Cat"></bean>

        執行時報空指針java.lang.NullPointerException。因爲按byName規則找不對應set方法,真正的setCat就沒執行,對象就沒有初始化,所以調用時就會報空指針錯誤。

 

    1.3autowire byType (按類型自動裝配)

        使用autowire byType首先需要保證:同一類型的對象,在spring容器中唯一。如果不唯一,會報不唯一的異常。

複製代碼

<bean id="cat" class="com.hdu.autowire.Cat"></bean>
<bean id="dog" class="com.hdu.autowire.Dog"></bean>
    
<bean id="user" 
      class="com.hdu.autowire.User"
      autowire="byType">
</bean>

複製代碼

        將<bean id="cat" class="com.hdu.autowire.Cat"></bean> 改成

<bean id="catXXX" class="com.hdu.autowire.Cat"></bean>

        因爲是按類型裝配,所以並不會報異常,也不影響最後的結果。

        甚至將id屬性去掉,也不影響結果。

<bean class="com.hdu.autowire.Cat"></bean>

 

    1.4全局autowire

複製代碼

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd"  default-autowire="byName">
        
    <bean id="cat" class="com.hdu.autowire.Cat"></bean>
    <bean id="dog" class="com.hdu.autowire.Dog"></bean>
    
    <bean id="user" class="com.hdu.autowire.User" autowire="default"/>
    <bean id="user2" class="com.hdu.autowire.User" autowire="default"/>
    <bean id="user3" class="com.hdu.autowire.User" autowire="default"/>

</beans>

複製代碼

 

二.屬性註解

    jdk1.5開始支持註解,spring2.5開始全面支持註解。

    利用註解的方式注入屬性。

    ①spring引入context文件頭

    ②開啓屬性註解

複製代碼

<?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:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:util="http://www.springframework.org/schema/util"  xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/util 
        http://www.springframework.org/schema/util/spring-util.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">
        
    <context:annotation-config/>
</beans>

複製代碼

 

    2.1 @Autowired

        @Autowired是按類型自動轉配的,不支持id匹配。

        將User中的set方法去掉,加入@Autowired註解。

        其中這裏依賴一個的jar包。

複製代碼

 1 package com.hdu.autowire;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 
 5 public class User {
 6     @Autowired
 7     private Cat cat;
 8     @Autowired
 9     private Dog dog;
10     private String str;
11     
12     public Cat getCat() {
13         return cat;
14     }
15     
16     public Dog getDog() {
17         return dog;
18     }
19     
20     public String getStr() {
21         return str;
22     }
23 }

複製代碼

<context:annotation-config/>
    
<bean id="catXXX" class="com.hdu.autowire.Cat"></bean>
<bean id="dogXXX" class="com.hdu.autowire.Dog"></bean>
    
<bean id="user" class="com.hdu.autowire.User"></bean>

    @Autowired(required=false)   

    false,對象可以爲null;true,對象必須存對象,不能爲null。

 

    2.2 @Qualifier

        @Autowired是根據類型自動裝配的,加上@Qualifier則可以根據byName的方式自動裝配,其中@Qualifier不能單獨使用。

複製代碼

 1 package com.hdu.autowire;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.beans.factory.annotation.Qualifier;
 5 
 6 public class User {
 7     @Autowired
 8     @Qualifier(value="carXXX")
 9     private Cat cat;
10     @Autowired
11     @Qualifier(value="dogXXX")
12     private Dog dog;
13     private String str;
14     
15     public Cat getCat() {
16         return cat;
17     }
18     
19     public Dog getDog() {
20         return dog;
21     }
22     
23     public String getStr() {
24         return str;
25     }
26 }

複製代碼

 

    2.3 @Resource

    @Resource如有指定的name屬性,先按該屬性進行byName方式查找裝配;其次再進行默認的byName方式進行裝配;如果以上都不成功,則按byType的方式自動裝配。都不成功,則報異常。

複製代碼

 1 package com.hdu.autowire;
 2 
 3 import javax.annotation.Resource;
 4 
 5 public class User {
 6     @Resource
 7     private Cat cat;
 8     @Resource(name="dogXXX")
 9     private Dog dog;
10     private String str;
11     
12     public Cat getCat() {
13         return cat;
14     }
15     
16     public Dog getDog() {
17         return dog;
18     }
19     
20     public String getStr() {
21         return str;
22     }
23 }

複製代碼

配置文件1:

<bean id="catXXX" class="com.hdu.autowire.Cat"></bean>
<bean id="cat" class="com.hdu.autowire.Cat"></bean>
<bean id="dogXXX" class="com.hdu.autowire.Dog"></bean>
    
<bean id="user" class="com.hdu.autowire.User"></bean>

  先進行byName查找,成功。

 

配置文件2:

<context:annotation-config/> 
    
<bean id="catXXX" class="com.hdu.autowire.Cat"></bean>
<bean id="dogXXX" class="com.hdu.autowire.Dog"></bean>
    
<bean id="user" class="com.hdu.autowire.User"></bean>

    先進行byName查找,失敗;再進行byType查找,成功。

 

配置文件3:

<bean id="catXXX" class="com.hdu.autowire.Cat"></bean>
<bean id="catYYY" class="com.hdu.autowire.Cat"></bean>
<bean id="dogXXX" class="com.hdu.autowire.Dog"></bean>
    
<bean id="user" class="com.hdu.autowire.User"></bean>

先進行byName查找,失敗;再進行byType查找,有兩個匹配,失敗,報錯。

 

    2.4小結:

    @Autowired與@Resource異同:

    1° @Autowired與@Resource都可以用來裝配bean。都可以寫在字段上,或寫在setter方法上。

    2° @Autowired默認按類型裝配(屬於spring規範),默認情況下必須要求依賴對象必須存在,如果要允許null 值,可以設置它的required屬性爲false,如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結合@Qualifier註解進行使用。

    3° @Resource(屬於J2EE復返),默認按照名稱進行裝配,名稱可以通過name屬性進行指定。如果沒有指定name屬性,當註解寫在字段上時,默認取字段名進行按照名稱查找,如果註解寫在setter方法上默認取屬性名進行裝配。 當找不到與名稱匹配的bean時才按照類型進行裝配。但是需要注意的是,如果name屬性一旦指定,就只會按照名稱進行裝配。

它們的作用相同都是用註解方式注入對象,但執行順序不同。@Autowired先byType,@Resource先byName。

 

三.類自動裝配

    3.1 包掃描

    註解替換bean節點
        @Controller註解       只能用控制器類上
        @Service註解           只能用在業務類上
        @Repository註解      只能用在dao類上
        @Component註解     無法按照上面三個註解分類,就用此註解 

複製代碼

 1 package com.hdu.autowire;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 @Component
 6 public class Cat {
 7     public void shout() {
 8         System.out.println("miao~");
 9     }
10 }

複製代碼

複製代碼

 1 package com.hdu.autowire;
 2 
 3 import org.springframework.stereotype.Component;
 4 
 5 @Component
 6 public class Dog {
 7     public void shout() {
 8         System.out.println("wang~");
 9     }
10 }

複製代碼

複製代碼

 1 package com.hdu.autowire;
 2 
 3 import javax.annotation.Resource;
 4 import org.springframework.stereotype.Component;
 5 
 6 @Component
 7 public class User {
 8     @Resource
 9     private Cat cat;
10     @Resource
11     private Dog dog;
12     private String str;
13     
14     public Cat getCat() {
15         return cat;
16     }
17     
18     public Dog getDog() {
19         return dog;
20     }
21     
22     public String getStr() {
23         return str;
24     }
25 }

複製代碼

複製代碼

<!-- 解析註解
     @Controller
     @Service
     @Repository
     @Component
     component-scan:組件掃描
     base-package:基本包,指定包名,多個包名可以用逗號間隔
     也可以寫多個<context:component-scan
     如果用了組件掃描後<context:annotation-config></context:annotation-config>就不用寫了,組件掃描已經包含了 <context:annotation-config>
-->
<context:component-scan base-package="com.hdu.autowire"/>

複製代碼

測試:

複製代碼

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.autowire.User;
 8 
 9 public class TestIOCDI {
10     @Test
11     public void testMethodAutowire() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_autowire.xml");
13         User user = context.getBean("user", User.class);
14         user.getCat().shout();
15         user.getDog().shout();
16     }
17 }

複製代碼

 

    3.2 類目和ID對應表:

        類名:    CAT        cAT         CaT        caT

        ID:          CAT         cAT        caT         caT

    分析:類名的關鍵在於第二個字母,第二個字母大寫,首字母大寫小寫無所謂。如果第二個字母小寫,那第一個必須小寫。第二個字母之後大小寫沒關係。

               如果沒有指定value,spring容器中id規則,是類名的首字母小寫。

 

    3.3 自定義bean的id

        @Component(value="cat")

 

四.其它註解

    4.1 @Value

jdbc_driverClass=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/tmpdb
jdbc_userName=root
jdbc_userPassword=root

        4.1.1${}表達式

<context:component-scan base-package="com.hdu.util"></context:component-scan>
<!-- 用$表達式方式 -->
<context:property-placeholder location="classpath:/resources/mysql.properties"/>

複製代碼

 1 package com.hdu.util;
 2 
 3 import org.springframework.beans.factory.annotation.Value;
 4 import org.springframework.stereotype.Component;
 5 
 6 @Component("jdbcUtil")
 7 public class JDBCUtil {
 8     @Value("${jdbc_driverClass}")
 9     private String driverClass;
10     @Value("${jdbc_url}")
11     private String url;
12     @Value("${jdbc_userName}")
13     private String userName;
14     @Value("${jdbc_userPassword}")
15     private String password;
16     public String getDriverClass() {
17         return driverClass;
18     }
19     
20     public String getUrl() {
21         return url;
22     }
23     
24     public String getUserName() {
25         return userName;
26     }
27     
28     public String getPassword() {
29         return password;
30     }
31     
32     @Override
33     public String toString() {
34         return "JDBCUtil [driverClass=" + driverClass + ", url=" + url + ", userName=" + userName + ", password="
35                 + password + "]";
36     }
37     
38     
39     
40 }

複製代碼

測試:

複製代碼

 1 package com.hdu.test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 import com.hdu.util.JDBCUtil;
 8 
 9 public class TestSpringIOCDI_Annoation {
10     @Test
11     public void testMethod() {
12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_annotation.xml");
13         JDBCUtil jdbcUtil = context.getBean("jdbcUtil", JDBCUtil.class);
14         System.out.println(jdbcUtil);
15     }
16 }

複製代碼

 

        4.1.2#{}表達式

<context:component-scan base-package="com.hdu.util"></context:component-scan>
<!-- 用#表達式方式 -->
<util:properties id="manyProperty" location="classpath:/resources/mysql.properties"></util:properties>

複製代碼

 1 package com.hdu.util;
 2 
 3 import org.springframework.beans.factory.annotation.Value;
 4 import org.springframework.stereotype.Component;
 5 
 6 @Component("jdbcUtil1")
 7 public class JDBCUtil1 {//@Value("#{manyProperty['jdbc_url']}")
 8     @Value("#{manyProperty.jdbc_driverClass}")
 9     private String driverClass;
10     @Value("#{manyProperty.jdbc_url}")
11     private String url;
12     @Value("#{manyProperty.jdbc_userName}")
13     private String userName;
14     @Value("#{manyProperty.jdbc_userPassword}")
15     private String password;
16     public String getDriverClass() {
17         return driverClass;
18     }
19     
20     public String getUrl() {
21         return url;
22     }
23     
24     public String getUserName() {
25         return userName;
26     }
27     
28     public String getPassword() {
29         return password;
30     }
31     
32     @Override
33     public String toString() {
34         return "JDBCUtil [driverClass=" + driverClass + ", url=" + url + ", userName=" + userName + ", password="
35                 + password + "]";
36     }
37 
38 }

複製代碼

測試:

複製代碼

package com.hdu.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hdu.util.JDBCUtil1;

public class TestSpringIOCDI_Annoation {
    @Test
    public void testMethod() {
        //加載spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_annotation.xml");
        //從spring容器中取出對象
        JDBCUtil1 jdbcUtil = context.getBean("jdbcUtil1", JDBCUtil1.class);
        System.out.println(jdbcUtil);
    }
}

複製代碼

 

 

    4.2 @Scope(value="prototype")// 單例和多例 修飾在類上 

    4.3 @Lazy //代表懶加載 修飾在類上 

    4.4 @PostConstruct //表示初始化操作 修飾在方法上

    4.5 @PreDestroy //表示銷燬 修飾在方法上

 

分類: web

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章