JavaEE開發之Spring中的條件註解、組合註解與元註解

上篇博客咱們詳細的聊了《JavaEE開發之Spring中的多線程編程以及任務定時器詳解》,本篇博客咱們就來聊聊條件註解@Conditional以及組合條件。條件註解說簡單點就是根據特定的條件來選擇Bean對象的建立。條件註解就是能夠根據不一樣的條件來作出不一樣的事情。在Spring中條件註解能夠說是設計模式中狀態模式的一種體現方式,同時也是面向對象編程中多態的應用部分。而組合註解就是將現有的註解進行組合。下方會給出具體的介紹和實例。html

 

1、條件註解----@Conditionaljava

本篇博客的本部分咱們來聊一下條件註解,顧名思義,條件註解就是能夠根據不一樣的條件來作出不一樣的事情。在Spring中條件註解能夠說是設計模式中狀態模式的一種體現方式,同時也是面向對象編程中多態的應用部分。git

Spring框架中,當咱們使用條件註解時,咱們會爲每種獨立的條件建立一個類,根據這個類對應的條件的成立狀況咱們來選擇不一樣的任務來執行。固然咱們在聲明任務時,通常使用接口來聲明。由於咱們會在Spring的配置類中指定具體條件下的具體類。接下來,咱們未來看一下Spring框架中@Conditional註解的具體使用方式。github

固然同一個Service接口所對應的條件集合中是互斥的,也就是說在特定狀況下只有一個條件成立。spring

 

一、建立服務接口以及具體的服務類編程

首先咱們來建立一個Service的接口,而後再基於遵循該接口的狀況下來建立兩個Service類。下方咱們將會在配置類中指定不一樣條件下會對應不一樣的Service對象。首先咱們先來建立Service的接口。下方這段代碼就是咱們建立的Service的接口,該接口比較簡單,只有一個描述方法。在具體是Service類中咱們將會給出description()方法的具體實現,用此方法來區分不一樣類的實現。設計模式

package com.zeluli.conditional;

public interface ConditinalServiceInteface {
    public String description();
}

 

建立完ServiceInterface後,咱們就該建立具體的類了。下方的FirstConditionServiceSecondConditionService兩個類都實現了ConditinalServiceInteface接口,而且給出了description()方法的具體實現。稍後,咱們將會在下方類配置Bean時,給出相應的條件。本小節只是準備部分。多線程

package com.zeluli.conditional;

public class FirstConditionService implements ConditinalServiceInteface {
    public String description() {
        return "第一個條件成立的Service";
    }
}


=========================================

package com.zeluli.conditional;

public class SecondConditionService implements ConditinalServiceInteface {
    public String description() {
        return "第二個條件成立的Service";
    }
}

 

二、建立@Conditional對應的條件類框架

建立完Service接口以及Service類後,接下來咱們就來建立@Conditional註解所需的條件類。每一個條件類對應着一種獨立的狀況,在Spring中的條件類須要實現Condition接口。下方是咱們建立的兩個條件類。post

這兩個條件類都實現了Spring框架中的Condition,而且給出了matches()方法的實現。matches()方法的返回值是一個布爾類型的值,若是返回false說明該條件類所對應的條件不成立,若是返回true則說明該條件對應的條件成立。爲了簡化操做,咱們就指定FirstConditional對應的條件爲false,而SecondConditional對應的條件爲true。具體的條件類的實現以下所示。

package com.zeluli.conditional;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class FirstConditional implements Condition {
    //提供條件的方法
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return false;
    }
}

==========================================

package com.zeluli.conditional;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class SecondConditional implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return true;
    }
}

 

3.在Java配置類中進行條件配置

Service的接口、Service的類以及相應的條件建立完畢後,接下來咱們就該在Java的配置類中將條件類與Service類對象進行關聯了。下方代碼段就是該部分對應的配置類。在聲明FirstConditionService類的Bean時,咱們使用@Conditional註解,@Conditional的參數爲FirstConditional.class,也就是說明當FirstConditional類所對應的條件成立時FirstConditionService的對象纔會被實例化。

同理,下方的SecondConditionService對應的條件是SecondConditional。具體代碼以下所示。

package com.zeluli.conditional;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.zeluli.conditional")
public class ConditionalConfig {
    
    @Bean
    @Conditional(FirstConditional.class) //指定條件類
    public FirstConditionService getFirstConditionalService() {
        return new FirstConditionService();
    }
    
    @Bean
    @Conditional(SecondConditional.class)
    public SecondConditionService getSecondConditionService() {
        return new SecondConditionService();
    }
}

 

四、建立Main方法進行測試

接下來又到了測試的時刻了,下方咱們從上面的ConditionalConfig配置類中獲取上下文,而後從上下文中獲取相應的Service對象。在獲取對象時,咱們使用的是ConditionalServiceInterface接口來獲取和聲明的Bean。也就是說service變量所承載的對象是實現ConditionalServiceInterface接口的全部類中的某個類的對象。當某個Service類所對應的條件成立時,該類的對象就會被建立。

上面咱們也提到過,ConditionalServiceInterface接口下每一個類對應的這些條件必須是互斥的,也就是這些條件在特定狀況下只有一個是成立的。由於咱們爲第二個條件返回的是true, 因此該條件是成立的,那麼SecondConditionalService類的對象就會被調用。因此咱們調用service的description()方法時,調用的是SecondConditionalService類中的相應的方法。具體以下所示。

 

  

 

 

2、組合註解

組合註解這個就比較好理解了,就是將多個註解組合到一塊生成一個新的註解。使用這個新的註解就至關於使用了該組合註解中全部的註解。這個特性仍是蠻有用的,接下來咱們就來看一下如何建立和使用組合註解。

 

1.組合註解的建立

接下來咱們就經過一個簡單的實例來看一下如何將多個註解組合到一塊。在以前的Spring配置類中,咱們常常使用到@Configuration@ComponentScan這兩個註解,接下來,咱們將其進行組合封裝,從而造成一個新的註解。

下方這個CombinationConfiguration註解就是咱們組合的新的註解,該註解中使用了@Configuration和@ComponentScan進行修飾,也就說明@CombinationConfiguration註解兼有@Configuration和@ComponentScan這兩個註解的功能。

package com.zeluli.combination.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@ComponentScan
public @interface CombinationConfiguration {
    String[] value() default{};
}

 

2.組合註解的使用

建立完相應的組合註解後就到了使用的時候了,上面註解的使用和通常的註解沒有什麼區別。只是這個註解表示以前寫的@Configuration和@ComponentScan這兩個註解。下方代碼截圖就是該組合註解的使用方式。

  

 

OK,今天博客就先到這兒吧,github源碼分享地址:https://github.com/lizelu/SpringDemo

相關文章
相關標籤/搜索