spring boot中的条件装配bean的实现

条件装配

从Spring Framework 3.1开始,允许在Bean装配时增加前置条件判断。

啥是条件装配

在bean装配前的条件判断。比如@Profile(是在spring3.1中引入),@Contditional(spring4.0中引入)
实现方式:注解方式,编程方式。

假设我们现在有一个多数据求和计算的小需求,定义两种方式Java7和Java8,然后使用条件装配的方式分别装配不同的bean。

首先我们定义一个接口

public interface CalculateService {

  /**
   * 从多个整数 sum 求和
   * @param values 多个整数
   * @return sum 累加值
   */
  Integer sum(Integer... values);
}

其次是两种不同的实现方式,Java7的方式

@Profile("Java7")
@Service
public class Java7CalculateService implements CalculateService {

  @Override
  public Integer sum(Integer... values) {
    System.out.println("Java 7 for 循环实现 ");
    int sum = 0;
    for (int i = 0; i < values.length; i++) {
      sum += values[i];
    }
    return sum;
  }

}

Java8的实现

@Profile("Java8")
@Service
public class Java8CalculateService implements CalculateService {

  @Override
  public Integer sum(Integer... values) {
    System.out.println("Java 8 Lambda 实现");
    int sum = Stream.of(values).reduce(0, Integer::sum);
    return sum;
  }

  public static void main(String[] args) {
    CalculateService calculateService = new Java8CalculateService();
    System.out.println(calculateService.sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
  }

}

我们在这里使用了@Profile("Java8")注解来表明对应的profile。然后我定义一个启动类在里面配置装配哪一个bean

@SpringBootApplication(scanBasePackages = "com.service")
public class CalculateServiceBootstrap {

  public static void main(String[] args) {
    ConfigurableApplicationContext context = new SpringApplicationBuilder(CalculateServiceBootstrap.class)
        .web(WebApplicationType.NONE)
        .profiles("Java8")
        .run(args);

    // CalculateService Bean 是否存在
    CalculateService calculateService = context.getBean(CalculateService.class);

    System.out.println("calculateService.sum(1...10) : " +
        calculateService.sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

    // 关闭上下文
    context.close();
  }
}

使用基于@ConditionalOnSystemProperty注解的方式实现。

首先我们定义一个注解,这里定义了一个属性和一个值。

/**
 * Java 系统属性 条件判断
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnSystemPropertyCondition.class)
public @interface ConditionalOnSystemProperty {

  /**
   * Java 系统属性名称
   * @return
   */
  String name();

  /**
   * Java 系统属性值
   * @return
   */
  String value();
}

定义一个条件判断的类,当这个类中的条件满足是才会装载bean,这个实现类实现org.springframework.context.annotation.Condition,AnnotatedTypeMetadata可以获取的到注解中的name和value信息,假设我们现在实现判断系统属性和注解中的配置的一样就加载bean,System.getProperty("user.name")获取当前系统下的用户名,我的mac创建的用户名叫yanghongxing,如果我们在注解中配置的value是yanghongxing则装载这个bean。

/**
 * 系统属性条件判断
 *
 */
public class OnSystemPropertyCondition implements Condition {

  @Override
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

    Map<String, Object> attributes = metadata.getAnnotationAttributes(ConditionalOnSystemProperty.class.getName());

    String propertyName = String.valueOf(attributes.get("name"));

    String propertyValue = String.valueOf(attributes.get("value"));

    String javaPropertyValue = System.getProperty(propertyName);

    return propertyValue.equals(javaPropertyValue);
  }
}

最后在启动类中启动

public class ConditionalOnSystemPropertyBootstrap {

  @Bean
  @ConditionalOnSystemProperty(name = "user.name", value = "yanghongxing")
  public String helloWorld() {
    return "Hello,World Honson";
  }

  public static void main(String[] args) {
    ConfigurableApplicationContext context = new SpringApplicationBuilder(ConditionalOnSystemPropertyBootstrap.class)
        .web(WebApplicationType.NONE)
        .run(args);
    // 通过名称和类型获取 helloWorld Bean
    String helloWorld = context.getBean("helloWorld", String.class);

    System.out.println("helloWorld Bean : " + helloWorld);

    // 关闭上下文
    context.close();
  }
}

我们可以在OnSystemPropertyCondition实现复杂的装载类的条件,判断是否装载某个bean。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2019-12-16

详解SpringBoot配置连接池

内置的连接池 目前spring Boot中默认支持的连接池有dbcp,dbcp2, tomcat, hikari三种连接池. 数据库连接可以使用DataSource池进行自动配置. 由于Tomcat数据源连接池的性能和并发,在tomcat可用时,我们总是优先使用它. 如果HikariCP可用,我们将使用它. 如果Commons DBCP可用,我们将使用它,但在生产环境不推荐使用它. 最后,如果Commons DBCP2可用,我们将使用它. 以上的几种连接池,可以通过在配置application文

Spring Boot环境属性占位符解析及类型转换详解

前提 前面写过一篇关于Environment属性加载的源码分析和扩展,里面提到属性的占位符解析和类型转换是相对复杂的,这篇文章就是要分析和解读这两个复杂的问题.关于这两个问题,选用一个比较复杂的参数处理方法PropertySourcesPropertyResolver#getProperty,解析占位符的时候依赖到 PropertySourcesPropertyResolver#getPropertyAsRawString: protected String getPropertyAsRawSt

Spring @Conditional注解讲解及示例详解

前言: @Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean. @Conditional的定义: //此注解可以标注在类和方法上 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { Class<? extends Condition>

解决Spring国际化文案占位符失效问题的方法

写在前面:接下来很长一段时间的文章主要会记录一些项目中实际遇到的问题及对应的解决方案,在相应代码分析时会直指问题所在,不会将无关的流程代码贴出,感兴趣的读者可以自行跟踪.同时希望大家能够将心得体会在评论区分享出来,让大家共同进步! 环境或版本:Spring 3.2.3 现象:利用Spring自带的MessageSource来处理国际化文案,us状态下的文案有部分占位符未被替换,cn状态下的正常.文案如下: tms.pallet.order.box.qty=The total palletized

在SpringBoot下读取自定义properties配置文件的方法

SpringBoot工程默认读取application.properties配置文件.如果需要自定义properties文件,如何读取呢? 一.在resource中新建.properties文件 在resource目录下新建一个config文件夹,然后新建一个.properties文件放在该文件夹下.如图remote.properties所示 二.编写配置文件 remote.uploadFilesUrl=/resource/files/ remote.uploadPicUrl=/resource

Spring Task定时任务的配置和使用详解

记录下Spring自带的定时任务用法. spring中使用定时任务 基于xml配置文件使用定时任务 首先配置spring开启定时任务 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/

Spring实战之容器后处理器操作示例

本文实例讲述了Spring实战之容器后处理器.分享给大家供大家参考,具体如下: 一 配置文件 <?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns:p=&

Spring实战之属性占位符配置器用法示例

本文实例讲述了Spring实战之属性占位符配置器用法.分享给大家供大家参考,具体如下: 一 配置文件 <?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xmlns

spring boot微服务自定义starter原理详解

这篇文章主要介绍了spring boot微服务自定义starter原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 使用spring boot开发微服务后,工程的数量大大增加(一定要按照领域来切,不要一个中间件客户端包一个),让各个jar从开发和运行时自包含成了一个重要的内容之一.spring boot starter就可以用来解决该问题(没事启动时别依赖于applicationContext.getBean获取bean进行处理,依赖关系

SpringBoot如何优雅的处理校验参数的方法

前言 做web开发有一点很烦人就是要校验参数,基本上每个接口都要对参数进行校验,比如一些格式校验 非空校验都是必不可少的.如果参数比较少的话还是容易 处理的一但参数比较多了的话代码中就会出现大量的IF ELSE就比如下面这样: 这个例子只是校验了一下空参数.如果需要验证邮箱格式和手机号格式校验的话代码会更多,所以介绍一下validator通过注解的方式进行校验参数. 什么是Validator Bean Validation是Java定义的一套基于注解的数据校验规范,目前已经从JSR 303的1.

读取spring配置文件的方法(spring读取资源文件)

1.spring配置文件 复制代码 代码如下: <bean id="configproperties"          class="org.springframework.beans.factory.config.PropertiesFactoryBean">          <property name="location" value="classpath:jdbc.properties"/>

java简单读取properties配置文件的方法示例

本文实例讲述了java简单读取properties配置文件的方法.分享给大家供大家参考,具体如下: 读取配置文件,小结如下 import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; public class loadConf { private Properties prop = new Properties(); private void loadconf() t

java读取properties配置文件的方法

本文实例讲述了java读取properties配置文件的方法.分享给大家供大家参考.具体分析如下: 这两天做java项目,用到属性文件,到网上查资料,好半天也没有找到一个满意的方法能让我读取到.properties文件中属性值,很是郁闷,网上讲的获取属性值大概有以下方法,以下三种方法逐渐优化,以达到最好的效果以下都以date.properties文件为例,该文件放在src目录下,文件内容为: startdate=2011-02-07 totalweek=25 方法一: public class

spring配置文件加密方法示例

Spring的配置文件是用于指导Spring工厂进行Bean生成.依赖关系注入及Bean示例分发的"图纸",他是一个或多个标砖的XML文档,J2EE程序员必须学会灵活应用这份"图纸",准确的表达自己的"生成意图".Spring配置文件是一个或多个标准的XML文档,applicationContext.xml是Spring的默认配置文件,当容器启动时找不到指定的配置文档时,将会尝试加载这个默认的配置文件. spring框架在一些对安全性要求较高的生

Python实现读取Properties配置文件的方法

本文实例讲述了Python实现读取Properties配置文件的方法.分享给大家供大家参考,具体如下: JAVA本身提供了对于Properties文件操作的类,项目中的很多配置信息都是放在了Properties文件.但是Python并没有提供操作Properties文件的库,所以,自己动手写个一个可以加载Properties文件的脚本. class Properties: fileName = '' def __init__(self, fileName): self.fileName = fi

Spring实战之FileSystemResource加载资源文件示例

本文实例讲述了Spring实战之FileSystemResource加载资源文件.分享给大家供大家参考,具体如下: 一 代码 package lee; import org.springframework.core.io.FileSystemResource; import org.dom4j.*; import org.dom4j.io.*; import java.util.*; import java.util.*; public class FileSystemResourceTest

监听器获取Spring配置文件的方法

我们在做项目的时候,会用到监听器去获取Spring的配置文件,然后从中拿出我们需要的bean出来,比如做网站首页,假设商品的后台业务逻辑都做好了,我们需要创建一个监听器,在项目启动时将首页的数据查询出来放到application里,即在监听器里调用后台商品业务逻辑的方法,也就是说我们需要在监听器里获取Spring中配置的相应的bean.先把监听器创建出来: 1. 创建InitDataListener 创建一个监听器InitDataListener继承ServletContextListener:

vs 中C#项目读取JSON配置文件的方法

config.json 文件内容如下 { "Data": { "DefaultConnection": { "ConnectionString": "Server=(localdb)\\MSSQLLocalDB;Database=Books;Trusted_Connection=True;" } }, "Appsettings": { "Name": "XiaoLi"

详解Java程序读取properties配置文件的方法

在我们平时写程序的时候,有些参数是经常改变的,而这种改变不是我们预知的.比如说我们开发了一个操作数据库的模块,在开发的时候我们连接本地的数据库那么IP ,数据库名称,表名称,数据库主机等信息是我们本地的,要使得这个操作数据的模块具有通用性,那么以上信息就不能写死在程序里.通常我们的做法是用配置文件来解决. 各种语言都有自己所支持的配置文件类型.比如Python ,他支持.ini 文件.因为他内部有一个ConfigParser 类来支持.ini 文件的读写,根据该类提供的方法程序员可以自由的来操作

使用spring工厂读取property配置文件示例代码

本文将介绍两种Spring读取property配置文件的方法,接下来看看具体内容. 一.通过Spring工厂读取 示例: public class PropertyConfig { private static AbstractBeanFactory beanFactory = null; private static final Map<String,String> cache = new oncurrentHashMap<>(); @Inject public Property