Spring 实战-第三章-条件化的bean

在使用的时候,某些bean需要在某些特定条件化才能实例化,spring中使用的@Condition注解实现这个功能。

1.接口

package main.java.soundsystem;
public interface CompactDisc {
    void play();
}

2.实现

package main.java.soundsystem;

import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
@Profile("dev")
public class SgtPepper implements CompactDisc {
    private String title ="Sgt. Pepper‘s Lonely Hearts Club Band";
    private String artist="The Beatles";
    @Override
    public void play() {
        System.out.println("Playing "+ title +" by "+artist);
    }
}

3.增加Condition实现类,需要实现Condition接口的matches方法,

方法返回true,表示使用这个条件的bean满足条件可创建,返回false,表示条件不满足,无法创建

package main.java.soundsystem;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class SgtPepperCondition implements Condition {

    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        return true;
    }
}

ConditionContext是一个接口,大致如下

public interface ConditionContext {
    BeanDefinitionRegistry getRegistry();
    ConfigurableListableBeanFactory getBeanFactory();
    Environment getEnvironment();
    ResourceLoader getResourceLoader();
    ClassLoader getClassLoader();
}

通过ConditionContext可以做到如下几点:

  • 借助getRegistry()返回的BeanDefinitionRegistry检查bean定义;
  • 借助getBeanFactroy()返回的ConfigurationListableBeanFactory检查bean是否存在,甚至探查bean的属性;
  • 借助getEnvironment()返回的Environment检查环境变量是否存在以及它的值是什么;
  • 读取并探查getResourceLoader()返回的ResourceLoader所加载的资源;
  • 借助getClassLoader()返回的ClassLoader加载并检查类是否存在。

4.配置增加条件

package main.java.soundsystem;
import org.springframework.context.annotation.*;

@Configuration
//@ComponentScan
public class CDPlayerConfig {

    @Bean
    @Conditional(SgtPepperCondition.class)
    @Profile("dev")
    public CompactDisc sgtPeppers() {
        return new SgtPepper();
    }

}

5.测试

package main.java.soundsystem;

import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {CDPlayerConfig.class})
@ActiveProfiles("dev")
public class CDPlayerTest {
    @Autowired
    private CompactDisc cd;

    @Test
    public void cdShouldNotBeNull() {
        assertNotNull(cd);
        cd.play();
    }

}
时间: 2024-08-10 02:08:40

Spring 实战-第三章-条件化的bean的相关文章

002Conditional条件化创建bean

01.条件化配置bean @Bean @Conditional(MagicExistsCondition.class)---->条件化创建bean public MagicBean magicBean(){ return new MagicBean(); } 02.条件接口 public interface Condition{ boolean matches(ConditionContext ctxt, AnnotatedTypeMetadata metadata); } 03.条件类实现 p

Spring高级装配(二) 条件化的bean

如果你希望一个bean在特定的条件下才会出现: 应用的类路径下包含特定的库时才创建 只有当某个特定的bean也声明之后才会创建 某个特定的环境变量设定之后才创建某个bean 在Spring 4之前,很难实现这种级别的条件化配置,但是Spring4引入了一个新的@Conditional注解,它可以用到带有@Bean注解的方法上.如果给定的条件计算结果为true,就会创建这个bean,否则的话,这个bean会被忽略. 示例:设置了magic环境属性才去实例化MagicBean 1 @Bean 2 @

《Spring实战 第三版》二

第二章 装配Bean 在Spring中,对象无需自己负责查找或创建与其相关联的其他对象 相反,容器负责把需要相互协作的对象引用赋予各个对象 创建应用对象之间协作关系的行为通常称为装配,这也是依赖注入的本质 声明Bean Spring是一个基于容器的框架 但是如果没有对Spring进行配置,那它就是一个空容器,不起任何作用 所以我们需要配置Spring来告诉它需要加载哪些Bean和如任何装配这些Bean 这样才能确保它们能够彼此协作 从Spring3.0开始,Spring容器提供了两种配置Bean

Spring实战第七章————SpringMVC配置的替代方案

SpringMVC配置的替代方案 自定义DispatherServlet配置 我们之前在SpittrWebAppInitializer所编写的三个方法仅仅是必须要重载的abstract方法.但还有更多的方法可以进行重载,从而实现额外的配置. 例如customizeRegistration().在AbstractAnnotationConfigDispatcherServletInitializer将DispatcherServlet主车道Servlet容器后,就会调用该方法,并将Servlet注

Spring实战第四章

,引言 在软件开发中,散布于应用中多处的功能被称为横切关注点(crosscuttingconcern).通常来讲,这些横切关注点从概念上是与应用的业务逻辑相分离的 DI有助于应用对象之间的解耦,而AOP可以实现横切关注点与它们所影响的对象之间的解耦. 一.面向切面编程 面向切面编程时,仍然在一个地方定义通用功能,但是可以通过声明的方式定义这个功能要以何种方式在何处应用,而无需修改受影响的类.横切关注点可以被模块化为特殊的类,这些类被称为切面(aspect).这样做有两个好处:首先,现在每个关注点

JAVA并发编程实战---第三章:对象的共享

在没有同步的情况下,编译器.处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整.在缺乏足够同步的多线程程序中,要对内存操作的执行顺序进行判断几乎无法得到正确的结果. 非原子的64位操作 当线程在没有同步的情况下读取变量时,可能会读到一个失效值,但至少这个值是由之前的某个线程设置,而不是一个随机值.这种安全性保证也被称为最低安全性. Java内存模型要求:变量的读取操作和写入操作都必须是原子操作,但对于非Volatile类型的long和Double变量,JVM允许将64的读操作或写操作

Java 8实战 第三章

Lambda函数特点: 匿名--写得少想的多. 函数--lambda有参数列表.函数主体.返回类型,有可以抛出的异常列表. 传递--lambda表达式可作为参数传递给方法或存储在变量中. 简介 Lambda隐含return语句(可以显式地使用return). Lambda有三个部分(更多示例: http://www.cnblogs.com/Hu-Yan/p/7955550.html) 参数列表 箭头 Lambda主体 return是一个控制流语句,要使它在lambda表达式中有效需要使用{}.

JAVA并发编程实战---第三章:对象的共享(2)

线程封闭 如果仅仅在单线程内访问数据,就不需要同步,这种技术被称为线程封闭,它是实现线程安全性的最简单的方式之一.当某个对象封闭在一个线程中时,这种方法将自动实现线程安全性,即使被封闭的对象本生不是线程安全的. 实现好的并发是一件困难的事情,所以很多时候我们都想躲避并发.避免并发最简单的方法就是线程封闭.什么是线程封闭呢? 就是把对象封装到一个线程里,只有这一个线程能看到此对象.那么这个对象就算不是线程安全的也不会出现任何安全问题.实现线程封闭有哪些方法呢? 1:ad-hoc线程封闭 这是完全靠

001profile条件化创建bean

01.类级别条件创建 @Configuration @Profile("dev") public class Aclass{}---->影响整个类,包括类的注解.开发环境,类中的配置才生效 02.方法级别条件创建 @Configuration poublic class AClass{ @Bean @Profile("dev")---->与@Bean一起使用,仅仅影响整个方法 public DataSource createDataSource(){ .