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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM