• @Conditional相关注解


    一、@Conditional

    @Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件的才给容器注册Bean。

    代码例子:

    package com.cy.conditional;
    
    /**
     * @description com.cy.conditional
     * @author: chengyu
     * @date: 2022-04-22 11:20
     */
    public interface ListService {
        public String showListCmd();
    }
    View Code
    package com.cy.conditional;
    
    /**
     * @description com.cy.conditional
     * @author: chengyu
     * @date: 2022-04-22 11:21
     */
    public class LinuxListService implements ListService{
        @Override
        public String showListCmd() {
            return "ls";
        }
    }
    View Code
    package com.cy.conditional;
    
    /**
     * @description com.cy.conditional
     * @author: chengyu
     * @date: 2022-04-22 11:21
     */
    public class WindowsListService implements ListService{
        @Override
        public String showListCmd() {
            return "dir";
        }
    }
    View Code

    WindowsCondition:

    package com.cy.conditional;
    
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    /**
     * @description com.cy.conditional
     * @author: chengyu
     * @date: 2022-04-22 11:20
     */
    public class WindowsCondition implements Condition {
    
        @Override
        public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) {
            return arg0.getEnvironment().getProperty("os.name").contains("Windows");
        }
    
    }

    LinuxCondition:

    package com.cy.conditional;
    
    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    /**
     * @description com.cy.conditional
     * @author: chengyu
     * @date: 2022-04-22 11:19
     */
    public class LinuxCondition implements Condition {
    
        @Override
        public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) {
            return arg0.getEnvironment().getProperty("os.name").contains("Linux");
        }
    
    }

    配置类Config:

    package com.cy.conditional;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Conditional;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @description com.cy.conditional
     * @author: chengyu
     * @date: 2022-04-22 11:21
     */
    @Configuration
    public class ConditionConfig {
    
        @Bean
        @Conditional(WindowsCondition.class)
        public ListService windowsListService() {
            return new WindowsListService();
        }
    
        @Bean
        @Conditional(LinuxCondition.class)
        public ListService linuxListService() {
            return new LinuxListService();
        }
    
    }

    测试类:

    package com.cy.conditional;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * @description com.cy.conditional
     * @author: chengyu
     * @date: 2022-04-22 11:22
     */
    public class App {
        public static void main(String[] args) {
    
            ApplicationContext context = new AnnotationConfigApplicationContext(
                    ConditionConfig.class);
    
            ListService ls = context.getBean(ListService.class);
            System.out.println(context.getEnvironment().getProperty("os.name")
                    + "系统下的列表命令为:" + ls.showListCmd());
        }
    }

    console:

    Windows 10系统下的列表命令为:dir

    二、@ConditionalOnClass

    例如:@ConditionalOnClass(KafkaTemplate.class)

    表示:Spring工程中引用了Kafka的包 才会构建这个bean。就是说只有在classpath下能找到kafkaTemplate类才会构建这个bean。

    三、@ConditionalOnBean

    @ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)

    参考博客:https://www.cnblogs.com/qdhxhz/p/11027546.html

    代码例子:

    1.实体类:

    package com.cy.model;
    
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    /**
     * @description com.cy.model
     * @author: chengyu
     * @date: 2022-04-22 11:40
     */
    @Setter
    @Getter
    @ToString
    public class Mother {
        String name;
        int age;
        Son son;
    }
    View Code
    package com.cy.model;
    
    import lombok.Getter;
    import lombok.Setter;
    import lombok.ToString;
    
    /**
     * @description com.cy.model
     * @author: chengyu
     * @date: 2022-04-22 11:40
     */
    @Setter
    @Getter
    @ToString
    public class Son {
        String name;
        int age;
    }
    View Code

    2.配置类:

    package com.cy.conditional;
    
    import com.cy.model.Mother;
    import com.cy.model.Son;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    
    @Configuration
    public class ConditionConfig {
    
    
        /*@Bean
        public Son son(){
            Son s = new Son();
            s.setAge(10);
            s.setName("小明");
            return s;
        }*/
    
        @Bean
        @ConditionalOnBean(Son.class)
        public Mother mother(Son son){
            Mother m = new Mother();
            m.setAge(40);
            m.setName("小慧妈妈");
            m.setSon(son);
            return m;
        }
    }

    3.测试类:

    package com.cy.conditional;
    
    import com.cy.model.Mother;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
     * @description com.cy.conditional
     * @author: chengyu
     * @date: 2022-04-22 11:37
     */
    @Controller
    @Slf4j
    public class ConditionController {
    
        @Autowired(required = false)
        private Mother mother;
    
        @ResponseBody
        @RequestMapping("/testConditionOnBean")
        public void conditionOnBean() {
            System.out.println(mother);
        }
    }

    4.测试结果:

    a.当不存在Son实体类被注入时,如果private Mother mother上面直接是@Autowired时,启动就会报错:

    Field mother in com.cy.conditional.ConditionController required a bean of type 'com.cy.model.Mother' that could not be found.

    因此需要在@Autowired后面写上(required=false),required=false 的意思就是允许当前的Bean对象为null。正常启动后打印:null

    b.当打开Son @Bean的注释后,重新启动,控制台打印:

    Mother(name=小慧妈妈, age=40, son=Son(name=小明, age=10))

    四、其他的

    @ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)

    @ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)

    @ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)

    @ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)

    @ConditionalOnNotWebApplication(不是web应用)

    五、@ConditionalOnProperty

    @ConditionalOnProperty(prefix="person" name = "super.enable", matchIfMissing = false, havingValue = "true")  代表什么意思呢?

    也是控制配置类是否生效;配置为:person.super.enable

    prefix: 配置文件的前缀

    name: 配置的名字,name或value是必填项。

    havingValue: 与配置的值对比值,当两个值相同返回true,配置类生效。

    matchIfMissing: 当未找到对应配置是否匹配,默认不匹配。该属性为true时,配置文件中缺少对应的value或name的对应的属性值,也会注入成功。

    例如:@ConditionalOnProperty(prefix = "aspectLog", name = "enable",havingValue = "true", matchIfMissing = true)当配置文件有aspectLog.enable=true时开启,如果配置文件没有设置aspectLog.enable也开启。

    ---

  • 相关阅读:
    sql-trace-10046-trcsess-and-tkprof
    教你深入理解软件包的配置、编译与安装过程
    Java RESTful 框架的性能比较
    gcc、arm-Linux-gcc和arm-elf-gcc的组成及区别
    Linux线上系统程序debug思路及方法
    使用systemtap调试Linux内核 :www.lenky.info
    SystemTap使用技巧 1
    gvfs
    Systemtap examples, Network
    .NET 大型信息化建设标准基础数据管理平台
  • 原文地址:https://www.cnblogs.com/tenWood/p/16178037.html
Copyright © 2020-2023  润新知