Spring——@Autowired註解和啟動自動掃描的三種方式__spring

來源:互聯網
上載者:User

引用文章地址:

https://my.oschina.net/HeliosFly/blog/203902(重點推薦!!!!!)
http://wiki.jikexueyuan.com/project/spring/annotation-based-configuration/spring-autowired-annotation.html
https://www.tianmaying.com/tutorial/spring-auto-wiring
http://www.cnblogs.com/liuzy2014/p/6692781.html
http://blog.csdn.net/baple/article/details/17891755

前言:

@Autowired註解代碼定義

@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD,                        ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Autowired {    boolean required() default true;}

從上述定義中,我們可以得出@Autowired註解只有一個屬性即required屬性,此屬性的預設值為true,即預設情況下它要求依賴對象必須存在,如果不存在會出現null 指標等錯誤;如果允許為null,可以設定它required屬性為false.其中@Autowired註解和標註的變數的類的set和get方法無關,自動裝配的實現並不是依賴set方法的方式實現的.在xml中利用

<property name="" value="" />

這種方式是依賴對應類的set方法的方式實現的 @Autowired註解使用之前首先確定判斷一下此處能夠使用@Autowired註解.

一、 @Autowired註解使用情境介紹

(1)建構函式(2)成員變數(3)Setter方法(4)普通方法

二、 @Autowired註解所涉及的原理部分

其實在啟動spring IoC時,容器自動裝載了一個AutowiredAnnotationBeanPostProcessor後置處理器,當容器掃描到@Autowied、@Resource或@Inject時,就會在IoC容器自動尋找需要的bean,並裝配給該對象的屬性

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>  

注意事項:

在使用@Autowired時,首先在容器中查詢對應類型的bean,    如果查詢結果剛好為一個,就將該bean裝配給@Autowired指定的資料        如果查詢的結果不止一個,那麼@Autowired會根據名稱來尋找。        如果查詢的結果為空白,那麼會拋出異常。解決方案時,使用required=false    

上述過程說明了@Autowired註解預設是按照類型裝配注入的,預設情況下它要求依賴對象必須存在如果允許為null,可以設定它required屬性為false,如果想按照名稱來轉配注入,則需要結合@Qualifier一起使用;

三、 處理使用@Autowired註解出現自動裝配的歧義性問題

使用@Autowired註解的過程中,如果出現NoUniqueBeanDefinitionException異常,大多是因為自動裝配或者其他方式裝配所導致的歧義性.即一個介面存在兩個以上的實作類別.即在自動裝配的時候,可能出現因重名問題導致的NoUniqueBeanDefinitionException異常.

@Autowired是按類型進行裝配的,那麼我一個介面UserInterface,有多個實作類別

AImpl(@service(name="userInterface1")),BImpl(@service(name="userInterface2")

等等這些實作類別都加入了Spring容器,當在一個類中使用如下語句:

@Autowiredprivate IUserInterface userInterface;

在下面列舉一下了一下,上述問題以及類似的裝配歧義性解決問題方法.
方法一

首先加上註解@Qualifier來區分不同的執行個體.通過在實現介面的類上通過value屬性去命名不同的名稱,對於@Repository、@Service 和 @Controller 和 @Component四個註解都有類似value屬性可以設定,例如:

@Service(value="userServiceImpl")public class UserServiceImpl implements IUserService{}@Autowired@Qualifier("userServiceImpl")private IUserService userServiceImpl;

方法二

因為一個借口存在兩個以上的實作類別,也可以通過標識首選哪個bean,來解決歧義性問題.例如:

@Component@Primarypublic class UserServiceImpl implements IUserService{  }

此時,如果引用到了IUserService介面的實作類別注入,則首先注入@Promary註解標註的類,但是此時有一個問題,在同一個介面的實作類別中,你只能使用一次@Primary,如果對於AImpl和BImpl都使用了@primary,則還是會發生裝配的歧義性.此時,建議使用(1)的方式來解決歧義性問題.

<4>方法三

最後一種方式,可以使用自訂的限定符註解,但是此種情況很少出現,再次就不做介紹,可自行百度.

四、 Spring通過哪些特性實現自動裝配的?

Spring從兩個角度來實現自動化裝配:

(1)組件掃描(component scanning):Spring會自動探索應用上下文中所建立的bean.(2)自動裝配(autowiring):Spring自動滿足bean之間的依賴.

組件掃描和自動裝配組合在一起就能發揮出強大的威力,它們能夠將你的顯示配置降低到最少.

五、@Autowired和@Resource之間的區別

在本文只列舉出@Autowired和@Resource之間常見的表面區別,至於區別的原因需要查看Spring官方文檔中的@Autowired註解實現方式和Java中@Resource註解實現方式.

(1)、@Autowired預設是按照類型裝配注入的,預設情況下它要求依賴對象必須存在如果允許為null,可以設定它required屬性為false,如果想按照名稱來轉配注入,則需要結合@Qualifier一起使用;

(2)、@Resource預設是按照名稱來裝配注入的,只有當找不到與名稱匹配的bean才會按照類型來裝配注入;

(3)、@Resource註解是由J2EE提供,而@Autowired是由spring提供,故減少系統對spring的依賴建議使用@Resource的方式;

(4)、@Resource和@Autowired都可以書寫標註在欄位或者該欄位的setter方法之上

(5)、@Resource預設按照名稱裝配,當找不到與名稱匹配的bean才會按照類型裝配,可以通過name屬性指定,如果沒有指定name屬 性,當註解標註在欄位上,即預設取欄位的名稱作為bean名稱尋找依賴對象,當註解標註在屬性的setter方法上,即預設取屬性名稱作為bean名稱尋找 依賴對象.注意:如果沒有指定name屬性,並且按照預設的名稱仍然找不到依賴的對象時候,會回退到按照類型裝配,但一旦指定了name屬性,就只能按照名稱裝配了.

六、Spring是如何啟動自動掃描的

在這裡列舉出三種啟動自動掃描的方式.

方式一:此種情況下,針對比較特殊的情形,即項目中運用了SpringBoot,則可以利用@SpringBootApplication註解的方式啟動自動掃描功能.

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Application {    public static void main(String[] args) {        SpringApplication.run(Application.class, args);    }}

方式二:通過XML配置方式,啟動自動掃描功能.XML配置方式

<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">    <context:component-scan base-package="com.tianmaying" /></beans>

標籤將會開啟Spring Beans的自動掃描,並可設定base-package屬性,表示Spring將會掃描該目錄以及子目錄下所有被@Component標註修飾的類,對它們進行裝配。

方式三:通過Java配置方式,啟動自動掃描功能.

import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScan(basePackages = "com.cn.config")public class BlogSystemConfig {    /**     * 在這裡實現java方式的配置,     */}

在這裡給出一個具體的執行個體:

import org.apache.commons.dbcp.BasicDataSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScan(basePackages = "com.cn.config")public class DataSourceConfig {    @Bean(name="dataSource")//java配置方式,配置資料來源(dataSource)    public BasicDataSource dataSource(){        BasicDataSource dataSource = new BasicDataSource();        dataSource.setDriverClassName("org.postgresql.Driver");        dataSource.setUrl("jdbc:postgresql://127.0.0.1:5432/center_db?useUnicode=true&characterEncoding=UTF-8");        dataSource.setUsername("postgres");        dataSource.setPassword("123456");        dataSource.setInitialSize(5);        dataSource.setMaxActive(10);        return dataSource;    }}

關於@Configuration和@ComponentScan兩個註解:
(1)@Configuration表示這個Java檔案是一個設定檔,這類Java代碼的作用在於配置,要和普通的Java代碼區分開發,因此一般我們需要將其放在一個專門的包中,在代碼例子中是com.cn.config。

(2)@ComponentScan表示開啟Spring Beans掃描,類似於XML配置,這裡也可以可以設定basePackages屬性。
如果@ComponentScan註解沒有顯示去給其他的屬性賦值的話,比如此處給basePackages賦值了,如果沒有的話,@ComponentScan註解會掃描與配置類相同的包.

注意:

關於@Repository、@Service 和 @Controller 和 @Component四個註解的使用情形
在持久層、業務層和控制層分別採用 @Repository、@Service 和 @Controller 對分層中的類進行注釋,而用 @Component 對那些比較中立的類進行注釋.這裡就是說把這個類交給Spring管理,重新起個名字叫userManager,由於不好說這個類屬於哪個層面,就用@Component.

七、Spring存在幾種裝配方式?

目前,在Spring中,一共提供三種裝配方式:

    (1)基於標註的自動裝配    (2)基於XML配置的顯式裝配    (3)基於Java配置的顯式裝配

在實際項目中,一般是上述三種裝備方式都可能存在,不過基於標註的自動裝配方式是在項目中最常用的.通過給Java類增加相應的標註,就能夠啟用Spring隱式的Bean發現機制,並自動完成裝配過程.我們在開發中應該儘可能使用自動裝配,足以應付開發中的絕大多數情況.在某些情況下,基於XML配置和基於Java配置的顯式裝配會有用武之地,比如執行個體化一個第三方庫中的Bean.這種情況下,Java配置和XML配置我們優先使用Java配置,因為這是一種型別安全的方式,能夠在編譯時間就儘早發現錯誤.
關於上述所說的型別安全可以這樣理解:
如果使用字串的形式,在xml中類名或其他寫入程式碼方式提供的資訊,在開發時是發現不了的,會在運行時拋出異常。而使用Java配置形式,類名或其他寫入程式碼配置資訊寫錯的話,編譯時間就會提示錯誤,比如Eclipse中就會提示找不到類的錯誤資訊,這就避免了這種情況下的運行時異常,因此是更加安全的.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.