2021年10月5日
【springboot条件注解与配置】
1、@Autowired 的几种注入方式
(1)字段或者成员变量注入;
(2)setter注入;
(3)构造函数注入。
2、指定包扫描注解 @ComponentScan
@ComponentScan("包的全路径")
默认springboot 默认扫描的是 与启动类同级或者 启动类的子级文件中 被@Component注解标识的类,它会把这些类加入到IOC容器中去。
3、把bean注入到使用类中的几种策略方式
(1)通过 byname 或 bytype方式;
(2)@Qualifier 指定bean的名字;
(3)有选择的只注入一个bean,注释掉某个bean 上的 @Component;
(4)通过 在标识@Component注解的类上添加 @Primary 注解,来标明这个bean优先级最高。
例:两个类同时实现了 Person接口,但是 ImplA类 添加了 @Primary注解,所以在注入Person类型的bean时,ImplA这个bean的优先级最高。
把Person类型的bean 注入到 使用类中:
4、条件注解
(1)自定义条件注解:
@Conditional 注解,可以编写自定义条件注解,还要加上实现 Condition 接口。
package com.example.javabase.myCondition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
// 原理: 如果返回true,就会把bean 加入到容器中去,否则,不会加入到容器中
public class Mycondition implements Condition {
@Override
public boolean matches(
ConditionContext conditionContext,
AnnotatedTypeMetadata annotatedTypeMetadata
) {
return true;
}
}
使用自定义的条件注解:
@Configuration
public class JoinBeanToRQ {
@Bean
public A setABean() {
return new A("lxc", 20);
}
// 直接在 要添加到容器的bean上使用条件注解,参数是我们自己写的条件注解
@Bean
@Conditional(Mycondition.class)
public B setBBean() { return new B("B", 21); }
}
(2)Condition 接口的参数 - conditionContext
通过 ConditionContext 可以获取系统环境中的各种信息, 接口中的方法 getEnvironment() 可获取到配置文件中的属性:
public class Mycondition implements Condition {
@Override
public boolean matches(
ConditionContext conditionContext,
AnnotatedTypeMetadata annotatedTypeMetadata
) {
// 如果配置文件中的author.name属性值为 "lxc",那么返回true
String name = conditionContext.getEnvironment().getProperty("author.name");
return "lxc".equalsIgnoreCase(name);
}
}
例:
B实现了Person接口,在加入到IOC容器时,使用 @Conditional注解判断,如果配置文件中 有 author.name = lxc ,那么 B类会被加入到 IOC 容器中
在使用类中注入Person类型的bean
注入Person类型的bean:
(3)内置成品条件注解
1> @ConditionalOnProperty(value="key", havingValue="value")
下边案例中,如果配置文件中 放入author.name = lxc, A类会被加入到 ioc容器中;如果author.name = B , B类会被加入到容器中去。
@ConditionalOnProperty(value="key", havingValue="value", matchIfMissing=true)
参数三 matchIfMissing=true 是如果配置文件中,没有 key的时候, 被标识的类才会被加入到配置文件中去,起到一个默认值的作用。
第三个参数是非常有用的,在实际开发中,如果我们写了一个组件,组件的配置策略可以让开发者自己在配置文件中配置,当然,如果开发者没有在配置文件中配置,我们可以使用 该注解 使用默认的配置策略。
2> @ConditionalOnProperty(name="IOC容器中的bean名字") 只有IOC容器中有name="xxx" 的Bean,被标识类才会被加入到IOC容器中。
下边案例,只有IOC容器中有名字为 setBBean 的Bean,B类才会被加入到容器中去。
补充下:
使用 @Configuration 注解会把一组Bean加入到IOC容器中,此时,如果想用具体的Bean,Bean的名字就是 @Bean标注的方法的名字。
3> @ConditionalOnMissingBean(name="IOC容器中的bean名字") 与 @ConditionalOnBean相反, 只有IOC容器中没有name="xxx" 的Bean,被标识的类才会被加入到IOC容器中去:
补充(2022-03-12)
实际开发中,@ConditionalOnMissingBean 一个应用场景:
package com.example.springboottest1.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
/**
* 如果没有实例化RestTemplate,那么把RestTemplate作为Bean添加到ioc容器中去
* @return
*/
@Bean
@ConditionalOnMissingBean(RestTemplate.class)
public RestTemplate instanceHttp() {
return new RestTemplate();
}
}