• 在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties


    在Spring Boot中使用 @ConfigurationProperties 注解, @EnableConfigurationProperties

    但 Spring Boot 提供了另一种方式 ,能够根据类型校验和管理application中的bean。 这里会介绍如何使用@ConfigurationProperties
    继续使用mail做例子。配置放在mail.properties文件中。属性必须命名规范才能绑定成功。举例:
    1 protocol and PROTOCOL will be bind to protocol field of a bean
    2 smtp-auth , smtp_auth , smtpAuth will be bind to smtpAuth field of a bean
    3 smtp.auth will be bind to … hmm to smtp.auth field of a bean!

    Spring Boot 使用一些松的规则来绑定属性到@ConfigurationProperties bean 并且支持分层结构(hierarchical structure)。
    开始创建一个@ConfigurationProperties bean:

    复制代码
    package com.dxz.property;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @ConfigurationProperties(locations = "classpath:mail.properties", ignoreUnknownFields = false, prefix = "mail")

     Springboot 1.6+用PropertySources

    @ConfigurationProperties("mail")
    @PropertySources(@PropertySource("classpath:/mail.properties"))

    public class MailProperties {
        private String host;
        private int port;
        private String from;
        private String username;
        private String password;
        private Smtp smtp;
    
        // ... getters and setters
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    
        public String getFrom() {
            return from;
        }
    
        public void setFrom(String from) {
            this.from = from;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public Smtp getSmtp() {
            return smtp;
        }
    
        public void setSmtp(Smtp smtp) {
            this.smtp = smtp;
        }
        
        @Override
        public String toString() {
            return "MailProperties [host=" + host + ", port=" + port + ", from=" + from + ", username=" + username
                    + ", password=" + password + ", smtp=" + smtp + "]";
        }
    
        public static class Smtp {
            private boolean auth;
            private boolean starttlsEnable;
    
            public boolean isAuth() {
                return auth;
            }
    
            public void setAuth(boolean auth) {
                this.auth = auth;
            }
    
            public boolean isStarttlsEnable() {
                return starttlsEnable;
            }
    
            public void setStarttlsEnable(boolean starttlsEnable) {
                this.starttlsEnable = starttlsEnable;
            }
    
        }
    }
    复制代码

    如下属性中创建 ( mail.properties ):

    复制代码
    mail.host=localhost
    mail.port=25
    mail.smtp.auth=false
    mail.smtp.starttls-enable=false
    mail.from=me@localhost
    mail.username=duan
    mail.password=duan123456
    复制代码

    上例中我们用@ConfigurationProperties注解就可以绑定属性了。ignoreUnknownFields = false告诉Spring Boot在有属性不能匹配到声明的域的时候抛出异常。开发的时候很方便! prefix 用来选择哪个属性的prefix名字来绑定。
    请注意setters 和 getters 需要在@ConfigurationProperties bean中创建! 与@Value注解相反。

    我们需要用属性来配置 application。 有至少两种方式来创建@ConfigurationProperties。即可以搭配@Configuration 注解来提供 @Beans 也可以单独使用并注入 @Configuration bean。

    方案1:定义spring的一个实体bean装载配置文件信息,其它要使用配置信息是注入该实体bean

    复制代码
    package com.dxz.property3;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    
    @Component
    @ConfigurationProperties(locations = "classpath:mail.properties", ignoreUnknownFields = false, prefix = "mail")
    public class MailProperties {
        private String host;
        private int port;
        private String from;
        private String username;
        private String password;
        private Smtp smtp;
    
        // ... getters and setters
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    
        public String getFrom() {
            return from;
        }
    
        public void setFrom(String from) {
            this.from = from;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public Smtp getSmtp() {
            return smtp;
        }
    
        public void setSmtp(Smtp smtp) {
            this.smtp = smtp;
        }
        
        @Override
        public String toString() {
            return "MailProperties [host=" + host + ", port=" + port + ", from=" + from + ", username=" + username
                    + ", password=" + password + ", smtp=" + smtp + "]";
        }
    
        public static class Smtp {
            private boolean auth;
            private boolean starttlsEnable;
    
            public boolean isAuth() {
                return auth;
            }
    
            public void setAuth(boolean auth) {
                this.auth = auth;
            }
    
            public boolean isStarttlsEnable() {
                return starttlsEnable;
            }
    
            public void setStarttlsEnable(boolean starttlsEnable) {
                this.starttlsEnable = starttlsEnable;
            }
    
        }
    }
    复制代码

    启动及测试类:

    复制代码
    package com.dxz.property3;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @SpringBootApplication
    //@EnableConfigurationProperties(MailProperties.class)
    public class TestProperty3 {
    
        @Autowired
        private MailProperties mailProperties;
        
        @RequestMapping(value = "/hello", method = RequestMethod.GET)
        @ResponseBody
        public String hello() {
            System.out.println("mailProperties" + mailProperties);
            return "hello world";
        }
    
        public static void main(String[] args) {
            //SpringApplication.run(TestProperty1.class, args);
            new SpringApplicationBuilder(TestProperty3.class).web(true).run(args);
    
        }
    }
    复制代码

    结果:

    mailPropertiesMailProperties [host=localhost, port=25, from=me@localhost, username=duan, password=duan123456, smtp=com.dxz.property3.MailProperties$Smtp@37cebacb]

    方案2:@Bean+@ConfigurationProperties

    我们还可以把@ConfigurationProperties还可以直接定义在@bean的注解上,这是bean实体类就不用@Component和@ConfigurationProperties了
    复制代码
    package com.dxz.property4;
    
    
    public class MailProperties {
        private String host;
        private int port;
        private String from;
        private String username;
        private String password;
        private Smtp smtp;
    
        // ... getters and setters
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    
        public String getFrom() {
            return from;
        }
    
        public void setFrom(String from) {
            this.from = from;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public Smtp getSmtp() {
            return smtp;
        }
    
        public void setSmtp(Smtp smtp) {
            this.smtp = smtp;
        }
        
        @Override
        public String toString() {
            return "MailProperties [host=" + host + ", port=" + port + ", from=" + from + ", username=" + username
                    + ", password=" + password + ", smtp=" + smtp + "]";
        }
    
        public static class Smtp {
            private boolean auth;
            private boolean starttlsEnable;
    
            public boolean isAuth() {
                return auth;
            }
    
            public void setAuth(boolean auth) {
                this.auth = auth;
            }
    
            public boolean isStarttlsEnable() {
                return starttlsEnable;
            }
    
            public void setStarttlsEnable(boolean starttlsEnable) {
                this.starttlsEnable = starttlsEnable;
            }
    
        }
    }
    复制代码

    配置类(启动类)

    复制代码
    package com.dxz.property4;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    
    @SpringBootApplication
    public class TestProperty4 {
    
        @Bean
        @ConfigurationProperties(locations = "classpath:mail.properties", prefix = "mail")
        public MailProperties mailProperties(){
            MailProperties mp = new MailProperties();
            System.out.println("zheli " + mp);
            return mp;
    
        }
    
        public static void main(String[] args) {
            //SpringApplication.run(TestProperty1.class, args);
            new SpringApplicationBuilder(TestProperty4.class).web(true).run(args);
    
        }
    }
    复制代码

    测试类:

    复制代码
    package com.dxz.property4;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/task")
    public class TaskController {
    
    @Autowired 
    MailProperties mailProperties;
    
    @RequestMapping(value = {"/",""})
    public String hellTask(){
        System.out.println("mailProperties" +mailProperties);  
        return "hello task !!";
    }
    
    }
    复制代码

    结果:

    方案3:@ConfigurationProperties + @EnableConfigurationProperties

    我们和上面例子一样注解属性,然后用 Spring的@Autowire来注入 mail configuration bean:

    复制代码
    package com.dxz.property;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @ConfigurationProperties(locations = "classpath:mail.properties", ignoreUnknownFields = false, prefix = "mail")
    public class MailProperties {
        private String host;
        private int port;
        private String from;
        private String username;
        private String password;
        private Smtp smtp;
    
        // ... getters and setters
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    
        public String getFrom() {
            return from;
        }
    
        public void setFrom(String from) {
            this.from = from;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public Smtp getSmtp() {
            return smtp;
        }
    
        public void setSmtp(Smtp smtp) {
            this.smtp = smtp;
        }
        
        @Override
        public String toString() {
            return "MailProperties [host=" + host + ", port=" + port + ", from=" + from + ", username=" + username
                    + ", password=" + password + ", smtp=" + smtp + "]";
        }
    
        public static class Smtp {
            private boolean auth;
            private boolean starttlsEnable;
    
            public boolean isAuth() {
                return auth;
            }
    
            public void setAuth(boolean auth) {
                this.auth = auth;
            }
    
            public boolean isStarttlsEnable() {
                return starttlsEnable;
            }
    
            public void setStarttlsEnable(boolean starttlsEnable) {
                this.starttlsEnable = starttlsEnable;
            }
    
        }
    }
    复制代码

    启动类及测试类:

    复制代码
    package com.dxz.property;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @SpringBootApplication
    @EnableConfigurationProperties(MailProperties.class)
    public class TestProperty1 {
    
        @Autowired
        private MailProperties mailProperties;
        
        @RequestMapping(value = "/hello", method = RequestMethod.GET)
        @ResponseBody
        public String hello() {
            System.out.println("mailProperties" + mailProperties);
            return "hello world";
        }
    
        public static void main(String[] args) {
            //SpringApplication.run(TestProperty1.class, args);
            new SpringApplicationBuilder(TestProperty1.class).web(true).run(args);
    
        }
    }
    复制代码

    结果:

    请注意@EnableConfigurationProperties注解。该注解是用来开启对@ConfigurationProperties注解配置Bean的支持。也就是@EnableConfigurationProperties注解告诉Spring Boot 能支持@ConfigurationProperties。如果不指定会看到如下异常:

    Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.dxz.property.MailProperties] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

    注意: 还有其他办法 (Spring Boot 总是有其他办法!) 让@ConfigurationProperties beans 被添加 – 用@Configuration或者 @Component注解, 这样就可以在 component scan时候被发现了。

    总结:

    @ConfigurationProperties很方便使用。 比用@Value注解好吗? 在特定的方案中是的,这只是一个选择问题。
    看下Spring Boot的文档有更多的关于 typesafe configuration 属性

    属性文件自动提示

    一般在我们开发中,通过IDE打开属性文件会产生一个自动提示。这种自定义提示也可以使用到我们自定义配置类中。

    首先我们需要在项目中加入processor jar包

    dependencies {
        compileOnly "org.springframework.boot:spring-boot-configuration-processor"
    }

    第二步我们需要配置META-INF/spring-configuration-metadata.json文件来描述。但是代码量挺大的,为了方便我们可以通过IDE来生成,这里使用的是idea。

    在idea设置中搜索Annotation Processors,接下来勾住Enable annonation processing就完成了。

    我们可以在编译后的文件中看到自动生成的spring-configuration-metadata.json。

    附上配图:

  • 相关阅读:
    51nod 1138 【数学-等差数列】
    hdoj3665【简单DFS】
    hdoj3664【DP】
    51nod1270 【dp】
    51nod 1069【思维】
    关于一些数学符号和概率的阐述;
    51nod 1428【贪心】
    51nod 1133【贪心】
    51nod1127【尺取】
    51nod1126【矩阵快速幂】
  • 原文地址:https://www.cnblogs.com/cdchencw/p/12347748.html
Copyright © 2020-2023  润新知