上篇博客我们详细的聊了《JavaEE开发之Spring中的多线程编程以及任务定时器详解》,本篇博客我们就来聊聊条件注解@Conditional以及组合条件。条件注解说简单点就是根据特定的条件来选择Bean对象的创建。条件注解就是可以根据不同的条件来做出不同的事情。在Spring中条件注解可以说是设计模式中状态模式的一种体现方式,同时也是面向对象编程中多态的应用部分。而组合注解就是将现有的注解进行组合。下方会给出具体的介绍和实例。

一、条件注解----@Conditional

本篇博客的本部分我们来聊一下条件注解,顾名思义,条件注解就是可以根据不同的条件来做出不同的事情。在Spring中条件注解可以说是设计模式中状态模式的一种体现方式,同时也是面向对象编程中多态的应用部分。

在Spring框架中,当我们使用条件注解时,我们会为每种独立的条件创建一个类,根据这个类对应的条件的成立情况我们来选择不同的任务来执行。当然我们在声明任务时,一般使用接口来声明。因为我们会在Spring的配置类中指定具体条件下的具体类。接下来,我们将来看一下Spring框架中@Conditional注解的具体使用方式。

当然同一个Service接口所对应的条件集合中是互斥的,也就是说在特定情况下只有一个条件成立。

1、创建服务接口以及具体的服务类

首先我们来创建一个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";
}
}

2、创建@Conditional对应的条件类

创建完Service接口以及Service类后,接下来我们就来创建@Conditional注解所需的条件类。每个条件类对应着一种独立的情况,在Spring中的条件类需要实现Condition接口。下方是我们创建的两个条件类。

这两个条件类都实现了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();
}
}

4、创建Main方法进行测试

接下来又到了测试的时刻了,下方我们从上面的ConditionalConfig配置类中获取上下文,然后从上下文中获取相应的Service对象。在获取对象时,我们使用的是ConditionalServiceInterface接口来获取和声明的Bean。也就是说service变量所承载的对象是实现ConditionalServiceInterface接口的所有类中的某个类的对象。当某个Service类所对应的条件成立时,该类的对象就会被创建。

上面我们也提到过,ConditionalServiceInterface接口下每个类对应的这些条件必须是互斥的,也就是这些条件在特定情况下只有一个是成立的。因为我们为第二个条件返回的是true, 所以该条件是成立的,那么SecondConditionalService类的对象就会被调用。所以我们调用service的description()方法时,调用的是SecondConditionalService类中的相应的方法。具体如下所示。

  

二、组合注解

组合注解这个就比较好理解了,就是将多个注解组合到一块生成一个新的注解。使用这个新的注解就相当于使用了该组合注解中所有的注解。这个特性还是蛮有用的,接下来我们就来看一下如何创建和使用组合注解。

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

JavaEE开发之Spring中的条件注解组合注解与元注解的更多相关文章

  1. JavaEE开发之Spring中的条件注解、组合注解与元注解

    上篇博客我们详细的聊了<JavaEE开发之Spring中的多线程编程以及任务定时器详解>,本篇博客我们就来聊聊条件注解@Conditional以及组合条件.条件注解说简单点就是根据特定的条 ...

  2. JavaEE开发之Spring中Bean的作用域、Init和Destroy方法以及Spring-EL表达式

    上篇博客我们聊了<JavaEE开发之Spring中的依赖注入以及AOP>,本篇博客我们就来聊一下Spring框架中的Bean的作用域以及Bean的Init和Destroy方法,然后在聊一下 ...

  3. JavaEE开发之Spring中的多线程编程以及任务定时器详解

    上篇博客我们详细的聊了Spring中的事件的发送和监听,也就是常说的广播或者通知一类的东西,详情请移步于<JavaEE开发之Spring中的事件发送与监听以及使用@Profile进行环境切换&g ...

  4. JavaEE开发之Spring中的依赖注入与AOP

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  5. JavaEE开发之Spring中的依赖注入与AOP编程

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  6. JavaEE开发之Spring中的事件发送与监听以及使用@Profile进行环境切换

    本篇博客我们就来聊一下Spring框架中的观察者模式的应用,即事件的发送与监听机制.之前我们已经剖析过观察者模式的具体实现,以及使用Swift3.0自定义过通知机制.所以本篇博客对于事件发送与监听的底 ...

  7. JavaEE开发之SpringMVC中的自定义拦截器及异常处理

    上篇博客我们聊了<JavaEE开发之SpringMVC中的路由配置及参数传递详解>,本篇博客我们就聊一下自定义拦截器的实现.以及使用ModelAndView对象将Controller的值加 ...

  8. JavaEE开发之SpringMVC中的静态资源映射及服务器推送技术

    在上篇博客中,我们聊了<JavaEE开发之SpringMVC中的自定义拦截器及异常处理>.本篇博客我们继续的来聊SpringMVC的东西,下方我们将会聊到js.css这些静态文件的加载配置 ...

  9. JavaEE开发之SpringMVC中的自定义消息转换器与文件上传

    上篇博客我们详细的聊了<JavaEE开发之SpringMVC中的静态资源映射及服务器推送技术>,本篇博客依然是JavaEE开发中的内容,我们就来聊一下SpringMVC中的自定义消息转发器 ...

随机推荐

  1. javah的使用

    2.我们要开始写javah的命令,以便生成对应的C语言头文件 D:\我的文档\workspace\PrepareForExam\src>javah -classpath D:\我的文档\work ...

  2. [Hadoop] - Cannot run program "cmake"

    在编译hadoop的过程中,遇到缺少cmake命令的异常,异常信息为:Cannot run program "cmake" (in directory "/opt/wor ...

  3. spring中对象的注入方式

    平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程 ...

  4. LINUX RHEL6.5字符界面安装图形化桌面

    安装RHEL 6.5 系统,也是一波三折.好不容易把系统装上去了,发现没装图形化界面.重装倒是学会了,不过觉得太麻烦,于是有了今天. 查了很多帖子,然后自己一一尝试,发现都是说简单,只要 yum gr ...

  5. C#基础——集合及特殊集合

    集合 集合的基本信息: Systerm.Collections命名空间包含接口和类,这些接口和类定义各种对象(如列表.队列.位数组.哈希表和字典)的集合. Systerm.Collections.Ge ...

  6. ERP实施顾问工作中应努力做到哪些?

    1.树立并分享信誉 准确的为自己定位,并积极树立自己的信誉.从这样两个角度去考虑问题,一是从高层管理者的角度去思考行业竞争和公司运作的问题,一是从专业.细致的角度去考虑单据.报表.界面等数据处理的问题 ...

  7. Git如何检出指定目录或文件

    系统版本:Window 10,Git 版本:2.7.1 对于大型 Git 仓库,每次执行 Git 命令,都需要经过漫长的等待,特别是要经常执行的 git status 命令.下面是一个例子... 从 ...

  8. Pdf File Writer 中文应用(PDF文件编写器C#类库)

    该文由小居工作室(QQ:2482052910)    翻译并提供解答支持,原文地址:Pdf File Writer 中文应用(PDF文件编写器C#类库):http://www.cnblogs.com/ ...

  9. iOS回顾笔记(05) -- 手把手教你封装一个广告轮播图框架

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

  10. KoaHub.JS基于Node.js开发的mysql的node.js驱动程序代码

    mysql A node.js driver for mysql. It is written in JavaScript, does not require compiling, and is 10 ...