1. 程式人生 > >【Spring註解】四、自動裝配@[email protec

【Spring註解】四、自動裝配@[email protec

四、自動裝配

[email protected]&@Qualifier和@Primary

@Autowried是Spring2.5定義的自動裝配的註解,它可以對類成員變數、方法及建構函式進行標註,完成自動裝配的工作。 使用 @Autowired的使用來消除 set ,get方法。@Autowired 標註在方法上表示當前方法的自定義引數從容器中賦值,ioc容器預設賦值時,需要呼叫無參構造器後,再進行預設賦值,如果當前類只有一個有參的構造器,則@Autwried可以省略,並且該構造器的引數也預設從ioc容器中獲取。

我們建立Color介面、以及它的實現類Red和Bule來介紹@Autowried&@Qualifier和@Primary的用法

Color介面

public interface Color {
}

Red實現類

@Component
public class Red implements Color {
    public Red() {
        System.out.println("這是Red的 構造器");

    }
}

Flower類

@Component
public class Flower {
    @Autowired
    private Color color;

    @Override
    public String toString
() { return "Folwer{" +"color=" + color +'}'; } }

配置類 AutowriedConfig

@Configuration
@ComponentScan("com.daxiong.pojo.Autowired")
public class AutowriedConfig {
}

測試類

public class AutowriedConfigTest {
    private AnnotationConfigApplicationContext  annotationConfigApplicationContext = new
AnnotationConfigApplicationContext(AutowriedConfig.class); @Test public void testAutowired1() { Flower bean = annotationConfigApplicationContext.getBean(Flower.class); System.out.println(bean); } }

此時我們只在Spring容器中注入的一個Color的實現類Red,測試結果

只有red類時

新增Bule類

@Component
public class Bule implements Color {
    public Bule() {
        System.out.println("這是Bule 的 構造器");
    }
}

執行結果:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'flower': Unsatisfied dependency expressed through field 'color'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.daxiong.pojo.Autowired.Color' available: expected single matching bean but found 2: bule,red
.....
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.daxiong.pojo.Autowired.Color' available: expected single matching bean but found 2: bule,red

出現No qualifying bean of type ‘com.daxiong.pojo.Autowired.Color’ available的異常,原因是@Autowried是按照型別注入的,我們在Flower中注入的Color物件沒有指定型別,Spring容器不知道到底應該注入哪一個物件的原因。解決辦法有以下幾種方法:

  1. 使用@Qualifier註解,明確的指定注入型別

    @Qualifier(value="red")
    private Color color;

  2. 使用@Primary註解,預設指定的型別

    @Primary
    @Component
    public class Red implements Color {
       public Red() {
           System.out.println("這是Red的 構造器");
    
       }
    }
  3. 修改引數名

    @Component
    public class Flower {
        //修改color的屬性名為red
       @Autowired
       private Color red;
    
       @Override
       public String toString() {
           return "Folwer{" +"color=" + red +'}';
       }
    

    執行結果:

    @Qualifier

注意點:

如果在自動裝配時。Spring容器中沒有註冊對應的Bean,就會報錯

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.daxiong.pojo.Autowired.Color' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

我們也只需要在@Autowried後加上(required=true)即可

[email protected]&@Inject

@Resource和@Inject分別是在JSR250和JSR330規範中定義的註解,在Spring中也得到了支援使用方法和@Autowried的類似

@Resource預設是按照屬性來裝配的,沒有支援@Primary和reuired

@Inject支援@Primary,但時不支援reuired,需要匯入javax.Inject包

3.Aware注入Spring底層元件&原理

自定義元件想要使用Spring容器底層的一些元件比如ApplicationContext,BeanFactory,等等,都可以通過實現XXXAware,在建立物件時,會把呼叫介面規定的方法把指定的元件裝配進去。

實現原理,這些XXXAware介面,都有對應的XXXprocessor來處理

如ApplicationContextAware有ApplicationContextAwareProcessor來處理Spring原始碼:

 //實現了BeanPostProcessor介面,所以會在元件初始化的識貨呼叫
class ApplicationContextAwareProcessor implements BeanPostProcessor {
  //在元件賦值前呼叫 
  @Override
   public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
      AccessControlContext acc = null;
     //判斷是否為對應介面型別
      if (System.getSecurityManager() != null &&
            (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                  bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                  bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
         acc = this.applicationContext.getBeanFactory().getAccessControlContext();
      }

      if (acc != null) {
         AccessController.doPrivileged(new PrivilegedAction<Object>() {
            @Override
            public Object run() {
               invokeAwareInterfaces(bean);
               return null;
            }
         }, acc);
      }
      else {
        //進行賦值操作
         invokeAwareInterfaces(bean);
      }

      return bean;
   }

   private void invokeAwareInterfaces(Object bean) {
     //對應的介面進行賦值操作
      if (bean instanceof Aware) {
         if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
         }
         if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
         }
         if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
         }
         if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
         }
         if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
         }
         if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
         }
      }
   }
}

相關推薦

Spring註解自動裝配@<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="723307061d051b00171654322017011d07001117">[email&#160;protec

四、自動裝配 [email protected]&@Qualifier和@Primary @Autowried是Spring2.5定義的自動裝配的註解,它可以對類成員變數、方法及建構函式進行標註,完成自動裝配的工作。 使用 @Au

20自動裝配<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b895f8f9cdccd7cfd1cadddc">[email&#160;protected]a>&@Qualifier&am

20、自動裝配[email protected]&@Qualifier&@Primary 自動裝配:Spring 利用依賴注入(DI),完成對IOC容器中各個依賴關係賦值 20.1 @Autowired :自動注入 預設優先按照型別去容器中找對應的元件,appl

21自動裝配<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="95b8d5c7f0e6fae0e7f6f0">[email&#160;protected]a>&@Inject

21、自動裝配[email protected]&@Inject Spring 還支援使用@Resource(JSR250)和@Inject(JSR330)[Java規範的註解] AutowiredAnnotationBeanPostProcessor 完成解析自動裝配功能

25自動裝配<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="371a77674558515e5b52">[email&#160;protected]a>根據環境註冊bean

25、自動裝配[email protected]根據環境註冊bean 指定元件在哪個環境的情況下才能被註冊到容器中 加了環境標識的,只有這個環境被啟用才能註冊到元件中 預設是default環境 寫在類上,整個配置類的啟用的時候才能生效 沒有標註環境標識的bean,在任何環境下

SpringSpring高階話題<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="012c41446f60636d64">[email&#160;protected]a>***註解的工作原理

@EnableAspectJAutoProxy @EnableAspectJAutoProxy註解 啟用Aspect自動代理 <aop:aspectj-autoproxy/> 開啟對AspectJ自動代理的支援。 在用到AOP的

<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="297a595b40474e69685c5d465e405b4c4d">[email&#160;protected]a>註解自動裝配(轉發)

配置 調用方法 support autowired 信息 ann over 反射機制 test 1 配置文件的方法我們編寫spring 框架的代碼時候。一直遵循是這樣一個規則:所有在spring中註入的bean 都建議定義成私有的域變量。並且要配套寫上 get 和 se

Spring@<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4b0824253f392427272e390b192e3a3e2e383f062a3b3b22252c">[email&#160;pr

一 淺顯的感性理解 向瀏覽器宣告 @Controller 其作用簡單來說就是對瀏覽器宣告,此類為控制器類 @ResponseBody 作用在方法上,表明此函式返回的內容直接寫入HTTP Response物件 @RestController 是@ResponseBo

SpringSpring高階話題-計劃任務<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a68be6e3c8c7c4cac3f5c5cec3c2d3cacfc8c1">[email&#160;pr

進行本示例的演示,需要先配置好Maven和spring哦、 見:  http://blog.csdn.net/qq_26525215/article/details/53010442 分析 要實現計劃任務,首先通過在配置類註解@EnableScheduling來開

Spring定時任務詳解例項<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="92bfd2c1f1faf7f6e7fef7f6">[email&#160;protected]a>

最近在做專案,時間比較緊張,也有比較久沒寫部落格了。 現在專案的Redis快取需要用到定時任務,就學習了一下Spring 的@Scheduled註解。使用起來很簡單。 這個例子是建立在之前我的一篇部落格的例項上面的。 也就是架好了SSM框架。 SSM

<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="663516140f08012627131209110f140302">[email&#160;protected]a>註解自動裝配

1   配置檔案的方法 我們編寫spring 框架的程式碼時候。一直遵循是這樣一個規則:所有在spring中注入的bean 都建議定義成私有的域變數。並且要配套寫上 get 和 set方法。 Boss 擁有 Office 和 Car

問題解決<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5102021c7c110523303f22303225383e3f303d">[email&#160;protected]a>註解事務無

Spring SpringMVC MyBatis框架中[email protected]註解事務無效解決方法 SpringMVC-Spring-MyBatis框架 資料庫:SQL SERVER 2008 以前都是用的MySQL資料庫,沒有

Spring原始碼學習<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3b16167b7a4e4f544c52495e5f">[email&#160;protected]a>註解和啟動自動掃描的三種

引用文章地址: 前言: @Autowired註解程式碼定義 @Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD,

<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="396a494b50575e79784c4d564e504b5c5d">[email&#160;protected]a>註解自動裝配

1   配置檔案的方法   我們編寫spring 框架的程式碼時候。一直遵循是這樣一個規則:所有在spring中注入的bean 都建議定義成私有的域變數。並且要配套寫上 get 和 set方法。   Boss 擁有 Office 和 Car 型別的兩個屬性:       

Spring高級話題<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="b29ff2f7dcd3d0ded7">[email&#160;protected]a>***註解的工作原理

sso metadata bool logs tcl task ota -c ann 出自:http://blog.csdn.net/qq_26525215 @EnableAspectJAutoProxy @EnableAspectJAutoProxy註解 激活Aspe

轉載解決方案:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2f48465b6f48465b475a4d014c4042">[email&#160;protected]a>出現Permissi

遇到的問題 今天心血來潮,想將intellij上的專案程式碼放到GitHub上管理。 在進行新增遠端庫的時候,出現了:[email protected]出現Permission denied (publickey) 原因是 ./ssh目錄預設在C:\Users\VULCAN\.ssh,而我

spring <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="e5878a8a91a5a08b84878980bdbdbdbd">[email&#160;protected]a>註解程式設計模型分析

@EnableXXXX程式設計模型 在spring boot中,@EnableXXX註解的功能通常是開啟某一種功能。根據某些外部配置自動裝配一些bean,來達到開啟某些功能的目的。光說很抽象,要具體分析。 @Enable模型的實現方式基本有3種。一個基本的@

Spring註解<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7e53533e2e0c111817121b">[email&#160;protected]a>的使用

@Profile的作用:當容器根據標識啟用對應的@Profile註解時,其所關聯的bean類才會註冊到容器。但容器不能或找不到對應的@Profile,就不生成bean例項。 建立配置類MainConf

Spring註解開發<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="96a5bbbbd6dffbe6f9e4e2">[email&#160;protected]a> , FacotryBean 註冊

目錄 @ComponentScan註解用於掃描自己寫的類(@Controller,@Service,@Component,@Repository),用於加入IOC容器中 @Bean 可以把其他包或者自己寫的類加到IOC容器中 @Import 也可以辦

C++error LNK2019: 無法解析的外部符號 <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="a6f9f1cfc8ebc7cfc8e69790">[email&#160;protected

原因:c語言執行時找不到適當的程式入口函式 解決:對於控制檯應用程式 1.選單中選擇 Project->Properties, 彈出Property Pages視窗 2.在左邊欄中依次選擇:Configuration Properties->C/C++->

Shelllinux bash Shell特殊變數:Shell $0, $#, $*, <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4f6b0f">[email&#160;protected]<

在linux下配置shell引數說明 前面已經講到,變數名只能包含數字、字母和下劃線,因為某些包含其他字元的變數有特殊含義,這樣的變數被稱為特殊變數。  例如,$ 表示當前Shell程序的ID,即pid,看下面的程式碼: $echo $$ 執行結果 29949