SpringInAction 学习笔记:高级装配

高级装配


配置profile bean

spring为环境相关的bean提供的解决方案其实与构建时的方案没有太大区别,根据环境决定该创建那个bean和不该创建哪个bean,且这并不是在构建时决定的,而是等到运行时来确定,使同一个部署单元能够适用于所有环境

profile 的Java代码配置

使用@Profile注解指定某个bean属于哪一个profile

@Configuration
@Profile("dev")
public class ProfileConfig{

    @Bean
    public DataSource dataSource(){
        return new ...;
    }

}

上面的@Profile注解用在了类级别上,表明,这个配置类中的bean只有在 dev profile 激活
时才会创建,否则带有@Bean注解的方法都会被忽略掉

--------------------------
从spring3.2开始还可以在方法级别上使用@Profile注解,
方便将不同环境对应的bean放在同一个配置类中
@Configuration

public class ProfileConfig{

    @Bean
    @Profile("dev")
    public DataSource dataSource(){
        return new ....;
    }

}

没有指定profile的bean始终都会被创建,与激活那个profile无关。
在xml中配置profile

通过元素的profile属性配置

<beans xmlns=.......
    profile="dev" >

    <bean .../>
    ...
</beans>

还可以在根<beans>元素中嵌套定义<beans>元素,方便将不
同环境的配置放到同一个xml文件中

<beans xmlns=....... >

    <beans profile="qa">
        <bean ... />
    </beans>

    ...
</beans>


激活 profile

spring通过两个独立的属性:
- spring.profiles.active
- spring.profiles.default
来确定哪个profile处于激活状态
设置了active属性的话,就会根据他的值确定哪个profile是激活的,否则就会查找default的值,active和default均没有设置的话,那就没有激活的profile
可同时设置多种profile值用逗号分隔

设置这两个属性的方式
- 作为DispatcherServlet的初始化参数
- 作为Web应用的上下文参数
- 作为JNDI条目
- 作为环境变量
- 作为JVM的系统属性
- 在集成测试类上,使用@ActiveProfiles注解设置

在Web应用的web.xml文件中设置默认的profile

<web-app ..... >
    <context-param>//为上下文设置默认的profile
        <param-name>spring.profiles.default</param-name>
        <param-value>dev</param-value>
    </context-param>


    <servlet>
        ...
        <init-param>//为servlet设置默认的profile
            <param-name>spring.profiles.default</param-name>
            <param-value>dev</param-value>
        </init-param>
        ...
    </servlet>



按条件配置bean

应用场景:例如希望一个或多个bean只有在应用的类路径下包含特定的库时才创建,或希望某个bean只有在另外某个特定的bean也声明了之后才创建

spring 引入的新的注解 @Conditional ,他可以用到带有@Bean注解的方法上,如果给定的计算结果为true就会创建这个bean,否则这个bean会被忽略

假设有一个MagicBean的类,我们希望只有设置了magic环境属性的时候spring才会实例化这个类

@Bean
@Conditional(MagicExistsCondition.class)
public MagicBean magicBean(){
    return new MagicBean();
}

@Conditional 会通过Condition接口进行条件对比

public interface Condition{
    boolean matches(ConditionContext ctxt,AnnotatedTypeMetadata metadata);
}


设置给@Conditional的类可以是任意实现了Condition接口的类型

public class MagicExistsCondition implements Condition{

    public boolean matches(ConditionContext context,AnnotatedTypeMetadata metadata){
        Environment env = context.getEnvironment();
        return env.containsProperty("magic");
    }

}

------------------------
ConditionContext 是一个接口 大致如下

public ConditionContext{

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


AnnotatedTypeMetadata 则能让我们检查带有@Bean注解的方法上还有什么其他的注解,它也是一个接口


@Profile 本身也使用了 @Conditional注解
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值