目录
我们可以写一个简单的工厂类来实现条件注入Bean,那么其实我们可以在里面写入一些很复杂的条件:
public MyBeanFactoryBean implements FactoryBean<MyBean> {
// Using app context instead of bean references so that the unused
// dependency can be left uninitialized if it is lazily initialized
@Autowired
private ApplicationContext applicationContext;
public MyBean getObject() {
MyBean myBean = new MyBean();
if (true /* some condition */) {
myBean.setDependency(applicationContext.getBean(DependencyX.class));
} else {
myBean.setDependency(applicationContext.getBean(DependencyY.class));
}
return myBean;
}
// Implementation of isSingleton => false and getObjectType
}
如果您希望在应用程序上下文中只有一个依赖bean,那么使用factory bean创建依赖bean可能是一种更好的方法:
public MyDependencyFactoryBean implements FactoryBean<MyDependency> {
public MyDependency getObject() {
if (true /* some condition */) {
return new MyDependencyX();
} else {
return new MyDependencyY();
}
}
// Implementation of isSingleton => false and getObjectType
}
使用Spring表达式(SpEL)
<bean class="com.example.MyBean">
<property name="dependency" value="#{systemProperties['foo'] == 'bar' ? dependencyX : dependencyY}" />
</bean>
Property占位符
<bean class="com.example.MyBean">
<property name="dependency" ref="${dependencyName}" />
</bean>
Spring profiles
<!-- Default dependency which is referred by myBean -->
<bean id="dependency" class="com.example.DependencyX" />
<beans profile="myProfile">
<!-- Override `dependency` definition if myProfile is active -->
<bean id="dependency" class="com.example.DependencyY" />
</beans>
其他方法可以将bean定义标记为lazy init=“true”,但该定义仍将在应用程序上下文中注册(并且在使用不合格的自动连接时会使您的生活更加困难)。您还可以通过@Profile注释将概要文件与@Component-based bean一起使用。
Post processor
Spring提供了许多钩子点和SPI,你可以在其中参与应用程序上下文生命周期。
BeanFactoryPostProcessor可以读取和更改bean定义(例如,属性占位符${}解析是通过这种方式实现的)。
BeanPostProcessor可以处理bean实例。可以检查新创建的bean并使用它(例如@Scheduled annotation processing就是这样实现的)。
MergedBeanDefinitionPostProcessor是bean后处理器的扩展,可以在实例化之前更改bean定义(@Autowired annotation processing就是这样实现的)。
条件注解
先来看下条件接口,所有条件注解,都是通过扩展Condtion接口实现的:
@FunctionalInterface
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
@Conditional注解,就是利用Condition接口判断条件是否满足,来决定是否初始化并向容器注入Bean。
Spring中提供了一系列相关注解:
@ConditionalOnMissingBean:当指定Bean不存在时,才会创建当前类的Bean。
@ConditionalOnBean:当指定Bean存在时(@ConditionalOnBean(name=“dependedBean”)),才会创建当前类的Bean。
@Component
@ConditionalOnBean(name="dependedBean")
public class ToCreateBean {
// ...
}