前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring 中条件注解的作用

Spring 中条件注解的作用

作者头像
水货程序员
修改2018-12-03 16:14:53
2.3K0
修改2018-12-03 16:14:53
举报
文章被收录于专栏:javathings

Spring 中条件注解的作用

@Conditional 是 Spring 4.0 提供的新注解。条件注解,顾名思义就是根据不同的条件加载不同的 Bean 到容器中。条件是写在一个接口实现类中,该条件所在的方法会返回布尔类型值,true 的时候表示满足该条件。

Conditional 的定义如下:

代码语言:javascript
复制
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Conditional {
 
	/**
	 * All {@link Condition}s that must {@linkplain Condition#matches match}
	 * in order for the component to be registered.
	 */
	Class<? extends Condition>[] value();
 
}

可以看到,这个注解用于方法或者类。并且其中的 value 就是一个 condition 接口类型。condition 接口的定义如下:

Condition接口

代码语言:javascript
复制
public interface Condition {
 
	/**
	 * Determine if the condition matches.
	 * @param context the condition context
	 * @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
	 * or {@link org.springframework.core.type.MethodMetadata method} being checked.
	 * @return {@code true} if the condition matches and the component can be registered
	 * or {@code false} to veto registration.
	 */
	boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

当 condition 接口的 matches 方法满足的情况下,标注的 Bean 就可以加载。

下面演示一下用法,当环境是 dev 的时候,返回 dev 的 DataSource,环境是 prd 的时候,返回 prd 的 DataSource。

演示

新建如下几个文件

  1. DataSource 类。
  2. Config 类,用于配置 Bean。
  3. DevDataSourceCondition 类和 ProdDataSourceCondition 类,都是实现 Condition 接口的类,用于 Conditional 标注中的参数。
  4. Main 类,程序入口,Main 方法,观察不同的参数实现不同的实例。

DataSource类

代码语言:javascript
复制
package com.learn.entity;
 
public class DataSource {
	private String dataSourceName;
 
	public String getDataSourceName() {
		return dataSourceName;
	}
 
	public void setDataSourceName(String dataSourceName) {
		this.dataSourceName = dataSourceName;
	}
}

配置类

代码语言:javascript
复制
package com.learn;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
 
import com.learn.condition.DevDataSourceCondition;
import com.learn.condition.ProdDataSourceCondition;
import com.learn.entity.DataSource;
 
@Configuration
public class Config {
 
	@Bean(name="DataSource")
	@Conditional(DevDataSourceCondition.class)//条件注解,满足该条件就会加载这个类到容器中
	public DataSource devDataSource()
	{
		DataSource d=new DataSource();
		d.setDataSourceName("dev");
		return d;
	}
	
	@Bean(name="DataSource")
	@Conditional(ProdDataSourceCondition.class)//条件注解,满足该条件就会加载这个类到容器中
	public DataSource prdDataSource()
	{
		DataSource d=new DataSource();
		d.setDataSourceName("prd");
		return d;
	}
 
}

条件接口的实现类。 DevDataSourceCondition

代码语言:javascript
复制
package com.learn.condition;
 
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
 
public class DevDataSourceCondition implements Condition {
 
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
	
		String env = context.getEnvironment().getProperty("application.env");
		return env.equalsIgnoreCase("dev");
	
	}
 
}

ProdDataSourceCondition

代码语言:javascript
复制
package com.learn.condition;
 
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
 
public class ProdDataSourceCondition implements Condition {
 
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		String env = context.getEnvironment().getProperty("application.env");
		return env.equalsIgnoreCase("pro");
	}
 
}

入口类,Main 方法

代码语言:javascript
复制
package com.learn;
 
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.learn.entity.DataSource;
 
public class Main {
 
	public static void main(String[] args) {
 
		//使用Config.class这个配置类
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
 
		System.out.println("实例个数:" + applicationContext.getBeanDefinitionCount());
		//遍历容器中的所有的实例的名字
		for (String n : applicationContext.getBeanDefinitionNames()) {
			System.out.println(n);
		}
 
		//根据类型获取实例
		DataSource ds=	applicationContext.getBean(DataSource.class);
		System.out.println("实例名字:" +ds.getDataSourceName());
		
		applicationContext.close();
	}
}

运行的时候,需要配置虚拟机参数,便于测试:

可以运行结果如下:

实例个数:10 org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory config org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor DataSource 实例名字:prd

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring 中条件注解的作用
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档