目录
1、@Bean
- value:标注bean在IOC容器中的id属性,spring容器通过该值获取bean,value和name功能相同,只能存在一个
- name:标注bean在IOC容器中的id属性,spring容器通过该值获取bean
- initMethod:指定初始化方法
- destoryMethod:指定销毁的方法
例如:
@Configuration
public class TestConfig {
/**
* name=demo,通过demo注册bean
* initMethod在bean初始化时候调用init()方法
* destroyMethod在bean生命周期结束销毁时调用destroy()方法,生命周期取决于bean的scope属性
*/
@Bean(name = "demo",
initMethod = "init",
destroyMethod = "destroy")
public Demo demo() {
return new Demo();
}
}
class Demo() {
public Demo() {}
public void init(){
System.out.println("我是初始化方法");
}
public void destroy() {
System.out.println("我是销毁方法");
}
}
2、@primary和@Qulifier
当一个接口有两个或多个实现时,@primary和@Qulifier都可以解决实现类的优先实现问题,区别点在于:
- @Primary:在实现类上标注,标识该实现类优先选择
- @Qulifier:在接口上标注,标识选择哪一个实现类
例如:
@Primary
public Integer People{
void declaration();
}
@Primary // 标识优先选择Man类进行实现
@Service
public class Man implements People{
void declaration() {
System.out.println("我是男生")
}
}
@Service
public class Woman implements People{
void declaration() {
System.out.println("我是女生")
}
}
public class test {
@Autowired
private People people;
public static void main(String[] args){
people.declaration();
}
}
@Qualifier
public interface People{
void declaration();
}
@Service("man")
public class Man implements People{
void declaration(){
System.out.println("我是男生");
}
}
@Service("woman")
@Bean(name = "woman")
public class WoMan implements People{
void declaration(){
System.out.println("我女生");
}
}
public class test{
@Qualifier("woman") // 标注选择woman的bean进行自动注入
@Autowire
private People people;
public static void main(Strings[] args) {
people.delcaration();
}
}
3、@ConditionalOnMissingBean
应用中不包含某个类时,对应的配置才生效,应用中包含该类的bean,那么二次注册同类型的bean的时候则会报错,一般该注解的使用会伴随着以下错误:
expected single matching bean but found 2
(该错误是由于系统已经注册过被@ConditionalOnMissingBean的bean,
然后就在别的地方注册了相同类型的bean,会提示不允许出现两个bean)
或者
expected at least 1 bean which qualifies as autowire candidate
(由于配置不生效,导致注册bean失败)
例子:
public class People{
public String name;
public String getName(){
return this.name;
}
public void setName(String name) {
this.name = name;
}
public People(){}
public People(String name) {
this.name = name;
}
}
@Configuration
public class TestConfig {
@Bean(name = "man")
public People man() {
return new People("我是男生");
}
@ConditionalOnMissingBean(People.class)
// 若应用中已经注册了上面的"man"bean,那么
// 如果再注册该"woman"的同类型People的bean,那么则会
// 报错:expected single matching bean but found 2......
@Bean("woman")
public People woMan() {
return new People("我是女生");
}
}
4、@ConditionalOnBean
该注解与ConditionalOnMissingBean注解相反,检查应用中是否拥有某个bean,若有,则生效。否则报错,一般伴随着以下错误:
```
expected at least 1 bean which qualifies as autowire candidate
```
条件化依赖:
条件依赖 | @ConditionalOnClass | 应用中包含某个类时,对应的配置才生效。 |
@ConditionalOnMissingClass | 应用中不包含某个类时,对应的配置才生效 | |
@ConditionalOnBean | Spring容器中存在指定class的实例对象时,对应的配置才生效 | |
@ConditionOnMissingBean | Spring容器中不存在指定class的实例对象时,对应的配置才生效 | |
@ConditionOnProperty | 指定参数的值符合要求时,对应配置才生效 | |
@ConditionOnResource | 指定资源存在时,对应的配置才生效 | |
@ConditionalOnWebApplication | 当前处于Web环境时(WebApplicationContext),对应的配置才生效 | |
@ConditionalOnExpression | 指定参数的值符合要求时,对应的配置才生效 | |
@ConditionalOnNotWebApplication | 当前处于非Web环境时,对应的配置才生效 | |
先后顺序 | @AutoConfigureAfter | 在指定的Configuration类之后加载 |
@AutoConfigureBefore | 在指定的Configuration类之前加载 | |
@AutoConfigrreOrder | 指定该configuration类的加载顺序,默认值0 |
5、以上注解的搭配使用
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Pepple{
Cat cat;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Cat{
String name;
}
@Configuration
public class TestConfig{
@Bean
public Cat cat(
return new Cat("我是一只小猫咪")
)
@Bean
public People peopleo2(Cat cat){
return new People(cat);
}
/**
* 代表优先注册该bean,并检查是否容器中拥有bean"cat",
* 若没有,配置失败,报错:expected at
* least 1 bean which qualifies as autowire candidate
* 以及检查容器中是否拥有people同类型的bean(例如上面的“people02”的
* bean已经提前手动注册了),
* 若有,则报错:expected single matching
* bean but found 2 :people,people02
*/
@Bean(name = {"people"},
destroyMethod = "destroy"
)
@Primary
@ConditionalOnBean({Cat.class})
@ConditionalOnMissBean(
name = {"people"}
)
public People people(Cat cat){
return new People(cat);
}
}
ps:部分知识点参考了一些文章中的思想,若有侵犯,联系整改或删除,(查的太广,忘记了记下博客链接);
文章中的代码并未经过测试,只是方便例子理解知识点!