目录

学习-springboot-Bean-管理注册条件

学习 springboot -Bean 管理(注册条件)

前言

上一篇 博客 : 我们了解了 bean 注册需要使用到 @Bean 和@Import  将第三方jar 包的对象 注入到ioc 容器

如下图所示

https://i-blog.csdnimg.cn/direct/862027efe84e434c90f5f78dc2650fe8.png 通过图片,可以看到Country 对象和Province 对象已经创建成功,现在我想要为Country 类中的 name 属性赋值

https://i-blog.csdnimg.cn/direct/19f99b4daa124f95b4418880d3c7fdc0.png

操作如下

在application.yml 配置文件给 属性name,system 赋值(差不多是这一个意思)

https://i-blog.csdnimg.cn/direct/eb8ea9751b4749aab74ab326b5252504.png

在CommonConfig 配置类中 使用@Value 注解为变量赋值

@Value 的使用场景

1 在成员变量上,为成员变量赋值

2 在方法的参数列表上为参数传递值

package com.it.heima.config;

import cn.itcast.pojo.Country;
import cn.itcast.pojo.Province;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ComonConfig {
    @Bean
    public Country getCountry(@Value("${Country.name}") String name, @Value("${Country.system}") String system){
        Country country = new Country();
        country.setName(name);
        country.setSystem(system);
        return country;
    }
    @Bean
    public Province getProvince() {
        return new Province();
    }
}

运行截图

https://i-blog.csdnimg.cn/direct/8b384646a98a4861bd10999a6584b852.png

发现,我们成功将 Country 类中的属性赋值


操作 :现在,如果把application.yml配置文件的内容注释掉,观察情况

https://i-blog.csdnimg.cn/direct/b6253b40965a4f8abfc5cf377069a149.png

问题

发现如果在配置文件中找不到指定映射信息,导致使用@Value 注解,无法映射到方法中的参数上,从而报错。

正文

如果使用一个注解可以随时管理注册条件:


如果配置文件有指定的信息,直接映射到方法参数上。

如果配置文件没有指定信息或者信息不对,不会因为使用@Value 注解无法映射而报错。

解决办法 :SpringBoot提供了设置注册生效条件的注解@Conditional

  • 由于直接使用这个注解比较麻烦,因此 使用该注解的衍生注解

https://i-blog.csdnimg.cn/direct/901ce5ab34d446c1ab739dc764930f16.png


注解@Conditional的衍生注解

1 @ConditionalOnProperty 注解

作用 :配置文件中,配置了指定信息,则注入,否则不注入到ioc 容器中

demo(案例)

预估结果 :因此接下来展示的例子是 配置文件中找不到指定信息,在启动类中使用getBean方法在ioc 容器中找不到 指定对象而报错

https://i-blog.csdnimg.cn/direct/5f6039a76c5b418e9c9ece0a806c8651.png

运行截图

https://i-blog.csdnimg.cn/direct/b231bc8c035148048d43bc8aea7c62f5.png


2 @ConditionalOnMissingBean 注解

作用 :如果 ioc 容器中不存在Country对象,则注入provice,否则不注入

demo(案例)

预测结果 :根据该注解的作用,我把 这两个注解都使用在配置类中,同时注释了配置文件中的信息,以及调用 getBean方法获得Country 对象,那么按理来说 应该打印 province 对象信息

CommonConfig 配置类

package com.it.heima.config;

import cn.itcast.pojo.Country;
import cn.itcast.pojo.Province;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ComonConfig {
    //配置文件中,配置了指定信息,则注入,否则不注入
   @ConditionalOnProperty(prefix = "Country" ,name={"name","system"})
    @Bean
    public Country getCountry(@Value("${Country.name}") String name, @Value("${Country.system}") String system){
        Country country = new Country();
        country.setName(name);
        country.setSystem(system);
        return country;
    }
    // 如果 ioc 容器中不存在Country对象,则注入provice,否则不注入
@ConditionalOnMissingBean(Country.class)
    @Bean
    public Province getProvince() {
        return new Province();
    }
}

运行截图

https://i-blog.csdnimg.cn/direct/c2f03bed874a49648dce8c7957157d50.png


3 @ConditionalOnClass 注解

作用 :如果当前环境中,存在DispatcherServlet类,则注入provice,否则不注入

  • 如果当前引入了web起步依赖,则存在DispatcherServlet类

格式:

@ConditionalOnClass(name={“DispatcherServlet的权限定类名”})

demo(案例)

预测结果:根据给注解的作用,可知 必须存在web的起步依赖才存在DispatcherServlet类,继而可以注入provice

<!--        web 的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

CommonConfig 配置类

package com.it.heima.config;

import cn.itcast.pojo.Country;
import cn.itcast.pojo.Province;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ComonConfig {
    //配置文件中,配置了指定信息,则注入,否则不注入
   @ConditionalOnProperty(prefix = "Country" ,name={"name","system"})
    @Bean
    public Country getCountry(@Value("${Country.name}") String name, @Value("${Country.system}") String system){
        Country country = new Country();
        country.setName(name);
        country.setSystem(system);
        return country;
    }
    // 如果 ioc 容器中不存在Country对象,则注入provice,否则不注入
  //@ConditionalOnMissingBean(Country.class)
 // 如果当前环境中,存在DispatcherServlet类,则注入provice,否则不注入
   // 如果当前引入了web起步依赖,则存在DispatcherServlet类,
   @ConditionalOnClass(name={"org.springframework.web.servlet.DispatcherServlet"})
    @Bean
    public Province getProvince() {
        return new Province();
    }
}

运行截图

https://i-blog.csdnimg.cn/direct/8b3c1815d9ba4f46a102937880636d15.png