上篇博客咱们详细的聊了《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后,咱们就该建立具体的类了。下方的FirstConditionService和SecondConditionService两个类都实现了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