spring在普通装配的功能上为我们提供了条件装配功能,一般来说,普通装配实现了bean的依赖注入功能,而条件装配则可以让我们实现根据不同条件,告诉spring在运行时确定要实例化哪些Bean。
根据环境条件的实现方式:
- 使用@Profile注解,profile的英文解释是轮廓,概述的意思,这里我们可以简单地理解为范围或者环境,使用@Profile注解,可以标注Bean属于什么profile,比如@Profile("dev"),就表示Bean只有在dev profile被激活时才会由spring管理并实例化,如果没有激活dev profile,那么spring就忽略这个Bean(注意:如果一个Bean没有被@Profile注解,那么表示这个Bean不受任何profile限制,spring会正常管理该Bean)。
- 在Xml的beans标签内定义profile属性。
接下来就要激活profile,让配置起作用:
spring提供了两个属性
spring.profiles.active和spring.profiles.default,如果没有设置spring.profiles.active,那么spring会查找pring.profiles.default,如果这两个属性都不设置,那么spring只会管理那些没有profile限制的bean。
- 在配置文件中设置
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>dev</param-value>
</context-param>
- 使用@ActiveProfiles注解
例如@ActiveProfiles("dev"),该方法一般用在测试类上,在测试的时候使用。
以上方法基于profile,也就是环境这个条件来装配bean,那么如果我们想使用其他条件怎么办呢?
spring给我们提供了@Conditional注解来实现条件定制。
下面写个简单的例子:判断指定文件是否存在,如果存在则会由spring实例化。
首先我们要定义一个类实现Condition接口,以下是Condition接口的源码:
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
实现类
public class FileExistsCondition implements Condition {
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getResourceLoader().getResource("test.txt").exists();
}
}
实现类的功能:判断是否存在test.txt文件,存在则返回true
然后我们写一个简单的类来使用@Condition注解
@Component
@Conditional(FileExistsCondition.class)
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
@Condition后面参数是具体的条件类
然后是主启动类
public class MainApp {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
obj.getMessage();
}
}
简单的调用helloWorld的getMessage()方法。
最后在项目的resource路径下添加test.txt文件。
运行程序的结果:
Your Message : null
成功调用了getMessage方法,说明HelloWorld成功被spring管理并实例化了(这里null是因为没有给message属性赋值)
假如我们删除test.txt文件呢?
看看运行结果:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'helloWorld' available
抛出了异常,说明spring没有创建HelloWorld实例。
以上实现了根据文件存在与否的条件来让spring选择是否装配指定Bean。
具体使用的时候可以根据需求来定制各种条件。