博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring boot将配置属性注入到bean 专题
阅读量:6234 次
发布时间:2019-06-22

本文共 15419 字,大约阅读时间需要 51 分钟。

hot3.png

@ConfigurationProperties和@value都是将外部属性注入到对象

@ConfigurationProperties很方便使用。 比用@value注解好吗? 在特定的方案中是的,这只是一个选择问题
@EnableConfigurationProperties //开启属性注入,有此注解就可以通过@autowired注入, 是配合@ConfigurationProperties使用的。
如果没有@EnableConfigurationProperties,则使用@ConfigurationProperties注解的class上面还需要添加@Component(@Component的包装注解,譬如

@Configuration、@Service也可以。但本质还是注解@Component)

@EnableAutoConfiguration在Spring boot中是启动自动配置的(Auto-configuration tries to be as intelligent as possible and will back-away as you define more of your own configuration.)

 

yml:

map结构:

复制代码

myProps: #自定义的属性和值    simpleProp: simplePropValue    arrayProps: 1,2,3,4,5    listProp1:   #List中的元素是Map    - name: abc        value: abcValue      - name: efg        value: efgValue    listProp2:      - config2Value1      - config2Vavlue2    mapProps:      key1: value1      key2: value2

复制代码

复制代码

@Component  @ConfigurationProperties(prefix="myProps") //接收application.yml中的myProps下面的属性  public class MyProps {      private String simpleProp;      private String[] arrayProps;      private List
> listProp1 = new ArrayList<>(); //接收prop1里面的属性值,List中的元素是Map private List
listProp2 = new ArrayList<>(); //接收prop2里面的属性值 private Map
mapProps = new HashMap<>(); //接收prop1里面的属性值 public String getSimpleProp() { return simpleProp; } //String类型的一定需要setter来接收属性值;maps, collections, 和 arrays 不需要 public void setSimpleProp(String simpleProp) { this.simpleProp = simpleProp; } public List
> getListProp1() { return listProp1; } public List
getListProp2() { return listProp2; } public String[] getArrayProps() { return arrayProps; } public void setArrayProps(String[] arrayProps) { this.arrayProps = arrayProps; } public Map
getMapProps() { return mapProps; } public void setMapProps(Map
mapProps) { this.mapProps = mapProps; } }

复制代码

http://blog.csdn.net/clementad/article/details/51970962

Take a look at the javadoc for ConfigurationProperties for more information on its various configuration options. For example, you can set a prefix to divide your configuration into a number of different namespaces:

@ConfigurationProperties(prefix="foo")

For the binding to work, you'd then have to use the same prefix on the properties declared in application.properties:

foo.users.alice=alpha

foo.users.bob=bravo

注入到Map类型的users字段中, alice和bob是map结构的key,等号后面的是value

 

一、@ConfigurationProperties注解的使用

看配置文件,我的是yaml格式的配置:

// file application.ymlmy:  servers:    - dev.bar.com    - foo.bar.com    - jiaobuchong.com

下面我要将上面的配置属性注入到一个Java Bean类中,看码:

import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import java.util.ArrayList;import java.util.List;@Component      //不加这个注解的话, 使用@Autowired 就不能注入进去了@ConfigurationProperties(prefix = "my")  // 配置文件中的前缀public class MyConfig {    private List
servers = new ArrayList
(); public List
getServers() { return this.servers; }}

下面写一个Controller来测试一下:

@RequestMapping("/test")@RestControllerpublic class HelloController {    @Autowired    private MyConfig myConfig;    @RequestMapping("/config")    public Object getConfig() {        return myConfig.getServers();    }}

下面运行Application.java的main方法跑一下看看:

@SpringBootApplicationpublic class Application {    public static void main(String[] args) {        // 启动Spring Boot项目的唯一入口        SpringApplication app = new SpringApplication(Application.class);        app.setBannerMode(Banner.Mode.OFF);        app.run(args);    }

在浏览器的地址栏里输入: 

localhost:8080/test/config 得到: 
[“dev.bar.com”,”foo.bar.com”,”jiaobuchong.com”] 
@EnableAutoConfiguration

复制代码

/** * Enable auto-configuration of the Spring Application Context, attempting to guess and configure beans that you are likely to need. Auto-configuration classes are usually
* applied based on your classpath and what beans you have defined. For example, If you * have {@code tomcat-embedded.jar} on your classpath you are likely to want a * {@link TomcatEmbeddedServletContainerFactory} (unless you have defined your own * {@link EmbeddedServletContainerFactory} bean). * 

* Auto-configuration tries to be as intelligent as possible and will back-away as you * define more of your own configuration. You can always manually {@link #exclude()} any * configuration that you never want to apply (use {@link #excludeName()} if you don't * have access to them). You can also exclude them via the * {@code spring.autoconfigure.exclude} property. Auto-configuration is always applied * after user-defined beans have been registered. *

* The package of the class that is annotated with {@code @EnableAutoConfiguration} has * specific significance and is often used as a 'default'. For example, it will be used * when scanning for {@code @Entity} classes. It is generally recommended that you place * {@code @EnableAutoConfiguration} in a root package so that all sub-packages and classes * can be searched. *

* Auto-configuration classes are regular Spring {@link Configuration} beans. They are * located using the {@link SpringFactoriesLoader} mechanism (keyed against this class). * Generally auto-configuration beans are {@link Conditional @Conditional} beans (most * often using {@link ConditionalOnClass @ConditionalOnClass} and * {@link ConditionalOnMissingBean @ConditionalOnMissingBean} annotations). * * @author Phillip Webb * @author Stephane Nicoll * @see ConditionalOnBean * @see ConditionalOnMissingBean * @see ConditionalOnClass * @see AutoConfigureAfter */@SuppressWarnings("deprecation")@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {

复制代码

 

二、@ConfigurationProperties和@EnableConfigurationProperties注解结合使用

在spring boot中使用yaml进行配置的一般步骤是, 

1、yaml配置文件,这里假设: 

my:  webserver:    #HTTP 监听端口    port: 80    #嵌入Web服务器的线程池配置    threadPool:      maxThreads: 100      minThreads: 8      idleTimeout: 60000

2、

复制代码

//file MyWebServerConfigurationProperties.javaimport org.springframework.boot.context.properties.ConfigurationProperties;@ConfigurationProperties(prefix = "my.webserver")  //没有使用@Component或@Confinguration,因此此对象不会注册到Spring容器中,需要@EnableConfigurationProperties引用public class MyWebServerConfigurationProperties {    private int port;    private ThreadPool threadPool;    public int getPort() {        return port;    }    public void setPort(int port) {        this.port = port;    }    public ThreadPool getThreadPool() {        return threadPool;    }    public void setThreadPool(ThreadPool threadPool) {        this.threadPool = threadPool;    }    public static class ThreadPool {        private int maxThreads;        private int minThreads;        private int idleTimeout;        public int getIdleTimeout() {            return idleTimeout;        }        public void setIdleTimeout(int idleTimeout) {            this.idleTimeout = idleTimeout;        }        public int getMaxThreads() {            return maxThreads;        }        public void setMaxThreads(int maxThreads) {            this.maxThreads = maxThreads;        }        public int getMinThreads() {            return minThreads;        }        public void setMinThreads(int minThreads) {            this.minThreads = minThreads;        }    }}

复制代码

 

3、

复制代码

// file: MyWebServerConfiguration.javaimport org.springframework.context.annotation.Configuration;import org.springframework.boot.context.properties.EnableConfigurationProperties;@Configuration@EnableConfigurationProperties(MyWebServerConfigurationProperties.class)public class MyWebServerConfiguration {    @Autowired    private MyWebServerConfigurationProperties properties;    /**     *下面就可以引用MyWebServerConfigurationProperties类       里的配置了    */   public void setMyconfig() {       String port = properties.getPort();       // ...........   }   }

复制代码

The @EnableConfigurationProperties annotation is automatically applied to your project so that any beans annotated with @ConfigurationProperties will be configured from the Environment properties. This style of configuration works particularly well with the SpringApplication external YAML configuration.(引自spring boot官方手册) 

三、@Bean配置第三方组件(Third-party configuration)

创建一个bean类:

复制代码

// file ThreadPoolBean.javapublic class ThreadPoolBean {    private int maxThreads;    private int minThreads;    private int idleTimeout;    public int getMaxThreads() {        return maxThreads;    }    public void setMaxThreads(int maxThreads) {        this.maxThreads = maxThreads;    }    public int getMinThreads() {        return minThreads;    }    public void setMinThreads(int minThreads) {        this.minThreads = minThreads;    }    public int getIdleTimeout() {        return idleTimeout;    }    public void setIdleTimeout(int idleTimeout) {        this.idleTimeout = idleTimeout;    }}

复制代码

 

引用前面第二部分写的配置类:MyWebServerConfiguration.java和MyWebServerConfigurationProperties.java以及yaml配置文件,现在修改MyWebServerConfiguration.java类:

import com.jiaobuchong.springboot.domain.ThreadPoolBean;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.context.properties.EnableConfigurationProperties;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configuration  //这是一个配置类,与@Service、@Component的效果类似。spring会扫描到这个类,@Bean才会生效,将ThreadPoolBean这个返回值类注册到spring上下文环境中@EnableConfigurationProperties(MyWebServerConfigurationProperties.class) //通过这个注解, 将MyWebServerConfigurationProperties这个类的配置到上下文环境中,本类中使用的@Autowired注解注入才能生效public class MyWebServerConfiguration {    @SuppressWarnings("SpringJavaAutowiringInspection") //加这个注解让IDE 不报: Could not autowire    @Autowired    private MyWebServerConfigurationProperties properties;    @Bean //@Bean注解在方法上,返回值是一个类的实例,并声明这个返回值(返回一个对象)是spring上下文环境中的一个bean    public ThreadPoolBean getThreadBean() {        MyWebServerConfigurationProperties.ThreadPool threadPool = properties.getThreadPool();        ThreadPoolBean threadPoolBean = new ThreadPoolBean();        threadPoolBean.setIdleTimeout(threadPool.getIdleTimeout());        threadPoolBean.setMaxThreads(threadPool.getMaxThreads());        threadPoolBean.setMinThreads(threadPool.getMinThreads());        return threadPoolBean;    }}

被@Configuration注解标识的类,通常作为一个配置类,这就类似于一个xml文件,表示在该类中将配置Bean元数据,其作用类似于Spring里面application-context.xml的配置文件,而@Bean标签,则类似于该xml文件中,声明的一个bean实例。 

写一个controller测试一下:

复制代码

import com.jiaobuchong.springboot.domain.ThreadPoolBean;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RequestMapping("/first")@RestControllerpublic class HelloController {    @Autowired    private ThreadPoolBean threadPoolBean;    @RequestMapping("/testbean")    public Object getThreadBean() {        return threadPoolBean;    }}

复制代码

 

运行Application.java的main方法, 

在浏览器里输入: 
得到的返回值是: 
{“maxThreads”:100,”minThreads”:8,”idleTimeout”:60000} 

http://blog.csdn.net/jiaobuchong/article/details/50442709

el最常用的几种使用场景:

  • 从配置文件中读取属性
  • 缺失值情况下,配置默认值
  • el内部字符串使用String的方法
  • 三目运算符
  • 正则表达式
  • 注入系统属性(system properties)
  • 调用系统原有函数
  • 直接注入文件进行操作
  • 读取另一个bean的函数的返回值

1、从配置文件中读取属性

application.properties

name=\u8D75\u8BA1\u521A
1     @Value("${name}")//这里必须使用$,使用#是不行的2     private String name;3     @RequestMapping(value = "/name", method = RequestMethod.GET)4     public String getName() {5         return name;6     }

注意:记住下边三句话

  • ${}不支持表达式(三目表达式不算表达式);#{}支持
  • ${}读取属性文件的值
  • ${}读取最后一个满足条件的值;#{}读取所有满足条件的值

2、缺失值情况下,配置默认值

1     @Value("${name2:'刚子'}")//这里必须使用$,使用#是不行的2     private String name2;3     @RequestMapping(value = "/name2", method = RequestMethod.GET)4     public String getName2() {5         return name2;6     }

3、el内部字符串使用String的方法

1 name.list=\u8D75\u8BA1\u521A,\u738B\u5A1C
1     @Value("#{'${name.list}'.split(',')}")2     private List
nameList;3 @RequestMapping(value = "/nameList", method = RequestMethod.GET)4 public List
getNameList() {5 return nameList;6 }

4、三目运算符

1 name.three=\u6768\u8FC7
1     @RequestMapping(value = "/nameThree", method = RequestMethod.GET)2     public String getNameThree(@Value("${name.three!='杨过'?'黄蓉':'小龙女'}") String nameThree) {3         return nameThree;4     }

注意:@value可以直接作为入参

5、正则表达式

1     @Value("#{'100' matches '\\d+'}")//这里必须使用#,使用$是不行的2     private boolean isDigital;3     @RequestMapping(value = "/nameRegEx", method = RequestMethod.GET)4     public boolean getNameRegEx() {5         return isDigital;6     }

6、注入系统属性

1     @Value("#{
systemProperties['os.name']}")//这里必须使用#,使用$是不行的2 private String osName;3 @RequestMapping(value = "/osName", method = RequestMethod.GET)4 public String getOsName() {5 return osName;6 }

7、调用系统原有函数

1     @Value("#{T(java.lang.Math).random() * 10}")//注意:这里只生成一次,之后你无论调用多少次getRandomValue(),都返回同一个值2     private String randomValue;3     @RequestMapping(value = "/randomValue", method = RequestMethod.GET)4     public String getRandomValue() {5         return randomValue;6     }

8、直接注入文件进行操作

testfile/testEl.txt

1 乔峰--降龙十八掌2 杨过--黯然销魂掌

复制代码

复制代码

1     @Value("classpath:testfile/testEl.txt") 2     private Resource txtResource; 3     @RequestMapping(value = "/resource", method = RequestMethod.GET) 4     public String getResource() { 5         try { 6             return IOUtils.toString(txtResource.getInputStream(), "UTF-8"); 7         } catch (IOException e) { 8             ExceptionUtils.getStackTrace(e); 9         }10         return StringUtils.EMPTY;11     }

复制代码

复制代码

注意:这个很重要,操作文件使用Apache.commons.io.IOUtils来操作。

9、读取另一个bean的函数的返回值

1 @Component("eLComponent")2 public class ELComponent {3     public String getNameBean(){4         return "乔峰";5     }6 }
1     @Value("#{eLComponent.getNameBean()}")//这里必须使用#,使用$是不行的2     private String nameBean;3     @RequestMapping(value = "/nameBean", method = RequestMethod.GET)4     public String getNameBean() {5         return nameBean;6     }

注意:被调用bean最好指定一下beanName。

http://www.cnblogs.com/java-zhao/archive/2016/07/01/5633881.html

application.properties中的配置:

db.driverClassName=com.mysql.jdbc.Driverdb.url=jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8&useSSL=falsedb.username=xxxdb.password=xxx

 

复制代码

import java.beans.PropertyVetoException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.core.env.Environment;import com.mchange.v2.c3p0.ComboPooledDataSource;@Configurationpublic class DBconfig {    @Autowired    private Environment env;    @Bean(name="dataSource")    public ComboPooledDataSource dataSource() throws PropertyVetoException {        ComboPooledDataSource dataSource = new ComboPooledDataSource();        dataSource.setDriverClass(env.getProperty("db.driverClassName"));        dataSource.setJdbcUrl(env.getProperty("db.url"));        dataSource.setUser(env.getProperty("db.username"));        dataSource.setPassword(env.getProperty("db.password"));        dataSource.setMaxPoolSize(20);        dataSource.setMinPoolSize(5);        dataSource.setInitialPoolSize(10);        dataSource.setMaxIdleTime(300);        dataSource.setAcquireIncrement(5);        dataSource.setIdleConnectionTestPeriod(60);        return dataSource;    }}

复制代码

转载于:https://my.oschina.net/xiaominmin/blog/1607725

你可能感兴趣的文章
mysql 插入超过1M字符串内容时,失败的解决办法
查看>>
超越传道:互联网时代的教与学
查看>>
android 安全讲座第五层(三) android so注入的研究
查看>>
vuejs7-v-for指令3
查看>>
我的友情链接
查看>>
Windows Server 笔记(六):Active Directory域服务:组
查看>>
通过组策略限制修改IP地址
查看>>
JS总结
查看>>
编写iptables脚本实现IP地址、端口过滤
查看>>
DNS服务练习
查看>>
C#抽象类和抽象方法
查看>>
iOS代码库开源软件
查看>>
C 链表
查看>>
【NetApp】no_atime_update卷选项
查看>>
【NetApp】SAN Switch的NPIV配置
查看>>
Citrix环境下,SQL Server 2012 R2镜像部署(一)
查看>>
Shell实际应用
查看>>
First Blog
查看>>
修改MySQL数据库字符编码为UTF-8解决中文乱码
查看>>
我的友情链接
查看>>