1. 程式人生 > >006-Spring Boot自動配置

006-Spring Boot自動配置

hid mis ase framework 增加 out jdk版本 art toc

一、接口Condition、Conditional(原理)

主要提供一下方法

boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

true:表示裝配

false:表示不裝配

註解:Conditional() 參數是數組,數組內的都是true才裝配

技術分享圖片
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface
Conditional { /** * All {@link Condition}s that must {@linkplain Condition#matches match} * in order for the component to be registered. */ Class<? extends Condition>[] value(); }
View Code

通常配合使用。

示例:

接口:EncodingConvert

技術分享圖片
package com.lhx.spring.springboot_auto_config;

public interface EncodingConvert { }
View Code

接口實現一:UTF8EncodingConvert

技術分享圖片
package com.lhx.spring.springboot_auto_config;

public class UTF8EncodingConvert implements EncodingConvert {

}
View Code

接口實現二:GBKEncodingConvert

技術分享圖片
package com.lhx.spring.springboot_auto_config;

public
class GBKEncodingConvert implements EncodingConvert { }
View Code

配置類:

技術分享圖片
package com.lhx.spring.springboot_auto_config;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;

@SpringBootConfiguration
public class EncodingConvertConfiguration {
    @Bean
    public EncodingConvert createGBKEncodingConvert() {
        return new GBKEncodingConvert();
    }

    @Bean
    public EncodingConvert createUTF8EncodingConvert() {
        return new UTF8EncodingConvert();
    }
}
View Code

App:

技術分享圖片
package com.lhx.spring.springboot_auto_config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.Conditional;

@SpringBootApplication
public class App {
    @Bean
    public Runnable createRunnable() {
        return () -> {
            System.out.println("spring boot is running");
        };
    }

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
        context.getBean(Runnable.class).run();
        //可以通過啟動參數修改-Dfile.encoding=GBK
        System.out.println(System.getProperty("file.encoding"));
        System.out.println(context.getBeansOfType(EncodingConvert.class));
        context.close();
    }
}
View Code

此時,會發現連個接口實現都會被裝配進來。

UTF8Condition實現Condition接口

技術分享圖片
package com.lhx.spring.springboot_auto_config;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class UTF8Condition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String encoding = System.getProperty("file.encoding");
        if (encoding != null) {
            return "utf-8".equalsIgnoreCase(encoding);
        }
        return false;
    }

}
View Code

GBKCondition實現Condition接口

技術分享圖片
package com.lhx.spring.springboot_auto_config;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class GBKCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String encoding = System.getProperty("file.encoding");
        if (encoding != null) {
            return "gbk".equalsIgnoreCase(encoding);
        }
        return false;
    }

}
View Code

修改配置類

技術分享圖片
package com.lhx.spring.springboot_auto_config;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;

@SpringBootConfiguration
public class EncodingConvertConfiguration {
    @Bean
    @Conditional(GBKCondition.class)
    public EncodingConvert createGBKEncodingConvert() {
        return new GBKEncodingConvert();
    }

    @Bean
    @Conditional(UTF8Condition.class)
    public EncodingConvert createUTF8EncodingConvert() {
        return new UTF8EncodingConvert();
    }
}
View Code

此時,會發現會根據file.encoding值來裝配接口類。

可在啟動參數增加

  -Dfile.encoding=GBK  

  技術分享圖片

然後調試,發現裝配類也變了

註意:@Conditional也可以作用在類上

二、Spring提供的Conditional自動配置

jar:spring-boot-autoconfigure中,org.springframework.boot.autoconfigure.condition;即spring-boot提供

ConditionalOnBean:當存在某個bean時候裝配

ConditionalOnMissingBean:當不存在某個bean時候裝配

ConditionalOnClass:當classpath有才裝配

ConditionalOnExpression:

ConditionalOnJava:JDK版本符合時候才裝配

ConditionalOnNotWebApplication:不是web環境才裝配
ConditionalOnWebApplication:是web環境才裝配

ConditionalOnResource:資源存在才裝配

ConditionalOnProperty:配置存在才裝配

示例一:ConditionalOnProperty 配置存在匹配時候才配置

增加配置類

技術分享圖片
package com.lhx.spring.springboot_auto_config;

import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;

@SpringBootConfiguration
public class UserConfiguration {

    @Bean
    @ConditionalOnProperty(name = "runnable.enable", havingValue = "true")
    public Runnable createRunnable() {
        return () -> {
        };
    }

}
View Code

App2編寫

技術分享圖片
package com.lhx.spring.springboot_auto_config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.Conditional;

@SpringBootApplication
public class App2 {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(App2.class, args);
        System.out.println(context.getBeansOfType(Runnable.class));
        context.close();
    }
}
View Code

默認是不能裝配的

可以再application.properties中添加runnable.enable=true即可裝配

或者@ConditionalOnProperty(name = "runnable.enable", havingValue = "true")增加

matchIfMissing=true,表示配置沒有的時候也生效

示例二:ConditionalOnClass classpath有某個類才裝配

增加或刪除maven,查看效果

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
        </dependency>

使用代碼

    @Bean
    @ConditionalOnClass(name="com.google.gson.Gson")
    public Runnable createGsonRunnable() {
        return () -> {
        };
    }

示例三、ConditionalOnBean:根據容器中是否存在某個Bean進行裝配

    @Bean
    @ConditionalOnBean(name="user")
    public Runnable createOnBeanRunnable() {
        return () -> {
        };
    }

006-Spring Boot自動配置