在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!html

Spring Boot 使用一些鬆的規則來綁定屬性到@ConfigurationProperties bean 而且支持分層結構(hierarchical structure)。
開始建立一個@ConfigurationProperties bean:web

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;
        }

    }
}

以下屬性中建立 ( mail.properties ):spring

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註解相反。json

 

咱們須要用屬性來配置 application。 有至少兩種方式來建立@ConfigurationProperties。便可以搭配@Configuration 註解來提供 @Beans 也能夠單獨使用並注入 @Configuration bean。app

方案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;
        }

    }
}

啓動及測試類:ide

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);

    }
}

結果:spring-boot

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);

    }
}

測試類:ui

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 !!";
}

}

結果:this

方案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。

附上配圖:

 

相關文章
相關標籤/搜索