Spring进阶_按条件进行Bean装配

Spring进阶_按条件进行Bean装配

1 环境与profile

在java配置中,可以使用@Profile注解指定某个bean属于哪一个profile。@Profile注解会告诉Spring这个配置类中的bean只有在dev profile激活时才会创建,如果dev profile没有激活的话,那么带有@Bean注解的方法都会被自动忽略。

@Configuration
@Profile("dev")
public class DevelopmentfileConfig {
    
    @Bean(destroyMethod = "shutdown")
    public DataSource dataSource(){
        // ...
    }
}

在方法级别上使用@Profile注解,与@Bean注解一同使用

@Configuration
public class DataSourceConfig {

    @Bean(destroyMethod = "shutdown")
    @Profile("dev")
    public DataSource embededDataSource(){
        // ...
    }

    @Bean
    @Profile("prod")
    public DataSource jndiDataSource(){
        // ...
    }
}
激活profile

激活spring.profiles.active属性值对应的profile值, 如果没有设置, 则激活spring.profiles.default对应的值,均没设置属性值,则只会创建没有定义再profile中的bean。

  • 作为DispatcherServlet的初始化参数
  • 作为web应用的上下文参数
  • 作为JNIDI条目
  • 作为环境变量
  • 作为JVM的系统属性
  • 在集成测试类上,使用@ActiveProfiles注解设置

在web应用的web.xml文件中设置默认的profile的代码如下:

....
<context-param>
	<param-name>spring.profiles.default</param-name>
	<param-value>dev</param-value>
</context-param>

...

<servlet>
    ...
    <init-param>
        <param-name>spring.profiles.default</param-name>
        <param-value>dev</param-value>
    </init-param>
    ...
</servlet>

环境发生变化,修改对应的即可

可以修改使用多个profile, 用逗号隔开就好

可以使用@ActiveProfiles(“dev”)激活dev profile

2 条件化的bean

假如你希望满足一定条件后,才会创建某个bean,可以使用@Conditional注解, 如果给定的条件结算结果为true,就会创建, 否则忽略。

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

在本例中,@Conditional将会通过Condition接口进行条件对比:

public interface Condition{
	boolean matches(ConditionContest xtxt, AnnotatedTypeMetadata metadata);
}

3 处理自动装配的歧义性

当一个接口有多个实现类, 而每个实现类都用@Component注解修饰, 当注入该接口时, 就会产生歧义,一般标示首选的bean(primary) @primary, 只能标志一个首选, 标志多个首选就会出现问题,实际开发情况比较少碰到这种情况。

@Component
@Primary
public class IceCream Iplents Dessert {...}
限定自动装配的bean

@Qualifier注解是使用限定符的主要方式。他可以与@Autowired和@Inject协同使用,在注入的时候指定想要注入进去的是哪个bean。

@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert){
	this.dessert = dessert;
}

@Qualifier注解的参数就是想要注入的bean的ID。

4 bean的作用域

默认情况, Spring 应用上下文中所有的bean都是作为以单例的形式创建的, Spring定义了多种作用域,可以基于这些作用于创建bean。

  • 单例(Singleton): 在整个应用中, 只创建bean一个实例
  • 原型(Prototype): 每次注入或者通过Spring应用上下文获取的时候, 都会创建一个新的bean实例
  • 会话(Session): 在web应用中, 为每个会话创建一个bean实例
  • 请求(Request): 在web应用中, 为每个请求创建一个bean实例

使用@Scope注解切换作用域, 它可以与@Component或@Bean一起使用

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Notepad{ ... }

使用XML来配置bean

<bean id="notepad" class="com.myapp.Notepad" scope="prototype"/>

每次注入或从Spring应用上下文中检索该bean的时候, 都会创建新的实例

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值