• Springboot学习笔记(五)-条件化注入


    前言

    将Bean交给spring托管很简单,根据功能在类上添加@Component,@Service,@Controller等等都行,如果是第三方类,也可以通过标有@Configuration的配置类来进行注入。但并不是所有被注入的bean都用得着,无脑注入会浪费资源。springboot提供了条件化配置,只有在满足注入条件才实例化。比如自定义一个ServiceHelloService,希望在spring.profiles.active=local时才加载。

    基础

    springboot中提供了Condition接口,实现它即可定义自己的条件:

    import org.springframework.context.annotation.Condition;
    import org.springframework.context.annotation.ConditionContext;
    import org.springframework.core.type.AnnotatedTypeMetadata;
    
    import java.util.Arrays;
    
    public class HelloCondition implements Condition {
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            return Arrays.stream(context.getEnvironment().getActiveProfiles())
                    .anyMatch("local"::equals);
        }
    }
    

    HelloService:

    import com.yan.springboot.condition.HelloCondition;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.Conditional;
    import org.springframework.stereotype.Component;
    
    @Component
    @Conditional(HelloCondition.class)
    public class HelloService {
        public void sayHi() {
            LoggerFactory.getLogger(HelloService.class).info("Hello World!");
        }
    }
    

    测试:

    import com.yan.springboot.service.HelloService;
    import org.junit.Assert;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    
    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ApplicationTest {
        @Autowired(required = false)
        private HelloService helloService;
    
        @Test
        public void test() {
            Assert.assertTrue(null == helloService);
        }
    }
    

    测试通过。
    此时在配置文件中加入spring.profiles.active=local则会报错(断言错误,helloService存在),可见它已生效。

    扩展

    Springboot中提供了很多条件化配置的注解,只要输入@ConditionalOn就能出现一大堆:

    不过比较常用的也就几种:

    /*******************
     *   Class包含Bean *
     ******************/
    
    // 容器中有ThreadPoolTaskExecutor类型的bean时才注入
    @ConditionalOnBean(ThreadPoolTaskExecutor.class)
    @ConditionalOnMissingBean(ThreadPoolTaskExecutor.class)
    // 类路径中有ThreadPoolTaskExecutor类型的bean时才注入
    @ConditionalOnClass(ThreadPoolTaskExecutor.class)
    @ConditionalOnMissingClass
    
    // 在配置文件中查找hello.name的值,如果能找到并且值等于yan,就注入,如果根本就没配,也注入,这就是matchIfMissing = true的含义
    @ConditionalOnProperty(prefix = "hello", name = "name", havingValue = "yan", matchIfMissing = true)
    
    //只在web环境下注入
    @ConditionalOnWebApplication
    
    // java8或以上环境才注入
    @ConditionalOnJava(ConditionalOnJava.JavaVersion.EIGHT)
    
  • 相关阅读:
    java 接口和抽象类的一个最大的区别
    python 简化数据结构的初始化二 支持关键字参数
    python 简化数据结构的初始化一
    python @staticmethod
    python @classmethod
    codeskulptor hosts
    An Introduction to Interactive Programming in Python (Part 1) -- Week 2_2 练习
    An Introduction to Interactive Programming in Python (Part 1) -- Week 2_1 练习
    mysql-5.7.14-winx64免安装版在win10下的详细配置过程
    python 反模式
  • 原文地址:https://www.cnblogs.com/yw0219/p/9062322.html
Copyright © 2020-2023  润新知