Spring Boot2.x-06Spring Boot基础-使用@Conditional注解根据特定的条件装配bean

简介: Spring Boot2.x-06Spring Boot基础-使用@Conditional注解根据特定的条件装配bean

概述


假设在某些特定的场景下,希望根据特定的条件去加载某个或某些bean,我们可以使用@Condtional注解, Spring 4.0的时候加入的这个注解。

20181027222643169.png

例子


假设,我们在配置了数据库的几个属性时,才去实例化bean,否则不初始化这个bean。这个例子可能不太合适,权当理解这个注解的用法了


Step1 实现Condition接口,重写matches方法

package com.artisan.springbootmaster.conditional;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
 *
 */
public class DatabaseCondtional implements Condition {
    /**
     * 数据库bean的装配条件
     *
     * @param context  上下文
     * @param metadata 注释类型的元数据
     * @return  true 装配Bean ,否则不装配
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 根据context取出对应的Env信息
        Environment environment = context.getEnvironment();
        // 判断属性文件是否存在对应的数据库配置
        return environment.containsProperty("datasource.driverName")
                && environment.containsProperty("datasource.url")
                && environment.containsProperty("datasource.username")
                && environment.containsProperty("datasource.password");
    }
}


Step2 在对应的@Bean上使用@Conditional注解

package com.artisan.springbootmaster.conditional;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
import java.util.Properties;
@Configuration
@PropertySource(value = "classpath:jdbc.properties",ignoreResourceNotFound = true)
public class Config {
    @Bean(name = "datasource" ,destroyMethod = "close")
    @Conditional(DatabaseCondtional.class)
    public DataSource initDataSource(
            @Value("${datasource.driverName}") String driver,
            @Value("${datasource.url}") String url,
            @Value("${datasource.username}") String username,
            @Value("${datasource.password}") String password){
        System.out.println("driver:" + driver + "\n url:" + url+ "\n username:" + username
        + "\n password:" + password) ;
        Properties properties = new Properties();
        properties.setProperty("driver",driver);
        properties.setProperty("url",url);
        properties.setProperty("username",username);
        properties.setProperty("password",password);
        DataSource dataSource = null;
        try {
            dataSource = BasicDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dataSource;
    }
}


测试

package com.artisan.springbootmaster.conditional;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import javax.sql.DataSource;
public class Test {
    public static void main(String[] args){
        ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
       //DataSource dataSource = (DataSource) ctx.getBean("datasource");
        DataSource dataSource = ctx.getBean(DataSource.class);
        System.out.println("datasource:" + dataSource);
    }
}


结果


20181027223818461.png


当我们修改掉某个属性后,DatabaseCondtional#matches方法肯定返回false, 按照推测,该bean不会被加载到IoC容器中,我们来验证下

将 datasource.driverName 改为 datasource.driverName1


20181027223948459.png

重新测试,抛出了异常。

20181027224026308.png


因为我们在获取bean的时候,IoC容器中并不存在该bean。


其他相关的注解


201810272247328.png

相关文章
|
2天前
|
SQL Java 数据库连接
Springboot框架整合Spring JDBC操作数据
JDBC是Java数据库连接API,用于执行SQL并访问多种关系数据库。它包括一系列Java类和接口,用于建立数据库连接、创建数据库操作对象、定义SQL语句、执行操作并处理结果集。直接使用JDBC涉及七个步骤,包括加载驱动、建立连接、创建对象、定义SQL、执行操作、处理结果和关闭资源。Spring Boot的`spring-boot-starter-jdbc`简化了这些步骤,提供了一个在Spring生态中更便捷使用JDBC的封装。集成Spring JDBC需要添加相关依赖,配置数据库连接信息,并通过JdbcTemplate进行数据库操作,如插入、更新、删除和查询。
|
2天前
|
SQL Java 数据库连接
Springboot框架整合Spring Data JPA操作数据
Spring Data JPA是Spring基于ORM和JPA规范封装的框架,简化了数据库操作,提供增删改查等接口,并可通过方法名自动生成查询。集成到Spring Boot需添加相关依赖并配置数据库连接和JPA设置。基础用法包括定义实体类和Repository接口,通过Repository接口可直接进行数据操作。此外,JPA支持关键字查询,如通过`findByAuthor`自动转换为SQL的`WHERE author=?`查询。
|
3天前
|
消息中间件 安全 Java
在Spring Bean中,如何通过Java配置类定义Bean?
【4月更文挑战第30天】在Spring Bean中,如何通过Java配置类定义Bean?
11 1
|
5天前
|
前端开发 Java 数据格式
【Spring系列笔记】定义Bean的方式
在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。
20 2
|
7天前
|
XML Java 数据格式
手写spring第七章-完成便捷实现bean对象初始化和销毁方法
手写spring第七章-完成便捷实现bean对象初始化和销毁方法
6 0
|
7天前
|
XML Java 数据格式
手写spring第六章-实现应用上下文,完成bean的扩展机制
手写spring第六章-实现应用上下文,完成bean的扩展机制
12 0
|
1月前
|
缓存 Java Spring
Spring 框架中 Bean 的生命周期
Spring 框架中 Bean 的生命周期
34 1
|
16天前
|
Java 数据库连接 开发者
浅谈Spring的Bean生命周期
浅谈Spring的Bean生命周期
20 1
|
6月前
|
XML Java 数据格式
Spring之Bean的生命周期
Spring之Bean的生命周期
56 0
|
2月前
|
Java Spring
Spring5深入浅出篇:bean的生命周期
Spring5深入浅出篇:bean的生命周期