首页 > 编程语言 > 详细

006-Spring Boot自动配置

时间:2018-01-22 22:05:54      阅读:229      评论:0      收藏:0      [点我收藏+]

一、接口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自动配置

原文:https://www.cnblogs.com/bjlhx/p/8326032.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!