SpringBoot 从application.yml中通过@Value读取不到属性值
package cn.exrick.xboot.mqtt;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@Configuration
public
class PubService {
private static final Logger log = LoggerFactory.getLogger(PubService.class);
private MqttConfig mqttConfig;
private static MqttClient client;
// 在构造函数中注入mqttConfig能获取到mqttConfig从application.yml中获取到的值
public
PubService(@Autowired MqttConfig mqttConfig) {
this.mqttConfig = mqttConfig;
init();
}
// @Bean
// public
// PubService pubService() {
// return new PubService();
// }
private
void init() {
try {
client = new MqttClient(mqttConfig.host, mqttConfig.clientId, new MemoryPersistence());
// client = new MqttClient("tcp://106.14.181.253:1883", "SmartStreet", new MemoryPersistence());
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setUserName(mqttConfig.userName);
connOpts.setPassword(mqttConfig.password.toCharArray());
connOpts.setConnectionTimeout(10);
connOpts.setKeepAliveInterval(20);
client.connect(connOpts);
client.setCallback(new PubServiceCallBack(client));
log.trace("Pub service client Connected");
} catch (MqttException e) {
log.error("build Pub service failed " + e.getMessage());
}
}
public
void publishTop() {
MqttMessage message = new MqttMessage();
message.setQos(2);
message.setRetained(true);
message.setPayload("{\"CHx\":\"ON\"}".getBytes());
try {
client.publish("Pub/80001001/CHx", message);
} catch (MqttException e) {
e.printStackTrace();
}
}
public static
void publishTop(String topic, MqttMessage msg) throws MqttException {
try {
client.publish(topic, msg);
} catch (MqttException e) {
log.error("public topic fail: Topic Name:\t" + topic + "fail message: " + e.getMessage());
e.printStackTrace();
throw e;
}
}
}
package cn.exrick.xboot.mqtt;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public
class MqttConfig {
@Value("${ssmqtt.host}")
public String host;
@Value("${ssmqtt.server.name}")
public String userName;
@Value("${ssmqtt.server.password}")
public String password;
@Value("${ssmqtt.clientId}")
public String clientId;
}
package cn.exrick.xboot.mqtt;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@Configuration
public
class PubService {
private static final Logger log = LoggerFactory.getLogger(PubService.class);
// 这种情况下,构造函数调用init方法就不能取到mqttConfig的值
@Autowired
private MqttConfig mqttConfig;
private static MqttClient client;
public
PubService() {
this.mqttConfig = mqttConfig;
init();
}
// @Bean
// public
// PubService pubService() {
// return new PubService();
// }
private
void init() {
try {
client = new MqttClient(mqttConfig.host, mqttConfig.clientId, new MemoryPersistence());
// client = new MqttClient("tcp://106.14.181.253:1883", "SmartStreet", new MemoryPersistence());
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setUserName(mqttConfig.userName);
connOpts.setPassword(mqttConfig.password.toCharArray());
connOpts.setConnectionTimeout(10);
connOpts.setKeepAliveInterval(20);
client.connect(connOpts);
client.setCallback(new PubServiceCallBack(client));
log.trace("Pub service client Connected");
} catch (MqttException e) {
log.error("build Pub service failed " + e.getMessage());
}
}
public
void publishTop() {
MqttMessage message = new MqttMessage();
message.setQos(2);
message.setRetained(true);
message.setPayload("{\"CHx\":\"ON\"}".getBytes());
try {
client.publish("Pub/80001001/CHx", message);
} catch (MqttException e) {
e.printStackTrace();
}
}
public static
void publishTop(String topic, MqttMessage msg) throws MqttException {
try {
client.publish(topic, msg);
} catch (MqttException e) {
log.error("public topic fail: Topic Name:\t" + topic + "fail message: " + e.getMessage());
e.printStackTrace();
throw e;
}
}
}
主要问题的原因就是,构造函数的执行顺序先于类属性的赋值。在构造函数中使用属性的值且从application.yml通过@Value获取,此时Spring容器还没有向属性赋值。这是Spring Bean的声明周期的属性造成的。
1 package com.aomi;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.List;
6 import static java.util.stream.Collectors.toList;
7
8 public class Main {
9
10 public static void main(String[] args) {
11 // TODO Auto-generated method stub
12
13 List<Student> stus = getSources();
14
15 Iterator<Student> ite = stus.iterator();
16
17 List<String> names = new ArrayList<>();
18 int limit = 2;
19 while (ite.hasNext() && limit > 0) {
20
21 Student stu = ite.next();
22
23 if (stu.getScore() > 5) {
24
25 names.add(stu.getName());
26 limit--;
27 }
28 }
29
30 for (String name : names) {
31 System.out.println(name);
32 }
33
34 }
35
36 public static List<Student> getSources() {
37 List<Student> students = new ArrayList<>();
38
39 Student stu1 = new Student();
40
41 stu1.setName("lucy");
42 stu1.setSex(0);
43 stu1.setPhone("13700227892");
44 stu1.setScore(9);
45
46 Student stu2 = new Student();
47 stu2.setName("lin");
48 stu2.setSex(1);
49 stu2.setPhone("15700227122");
50 stu2.setScore(9);
51
52 Student stu3 = new Student();
53 stu3.setName("lili");
54 stu3.setSex(0);
55 stu3.setPhone("18500227892");
56 stu3.setScore(8);
57
58 Student stu4 = new Student();
59
60 stu4.setName("dark");
61 stu4.setSex(1);
62 stu4.setPhone("16700555892");
63 stu4.setScore(6);
64
65 students.add(stu1);
66 students.add(stu2);
67 students.add(stu3);
68 students.add(stu4);
69
70 return students;
71 }
72
73 }
复制代码
如果用流的话是这样子的。
复制代码
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Student> stus = getSources();
List<String> names = stus.stream()
.filter(st -> st.getScore() > 5)
.limit(2)
.map(st -> st.getName())
.collect(toList());
for (String name : names) {
System.out.println(name);
}
}
复制代码
把这俩段代码相比较主要是为了说明一个概念:以前做法都是在外部迭代,最为体现就是笔者在外面定义了一个集合names 。而流却什么也没有,现在我们应该能清楚感受到流是在内部迭代。也就是说流已经帮你做好了迭代。我们只要传入相关的函数就可以得到想要的结果。至于内部迭代的好处,笔者没有办法亲身的感受,唯一的感觉就是代码变的简单明了了。但是官方说Stream库为了我们在内部迭代里面做了很多优化和充公利用性能的操作。比如并行操作。所以笔者就听官方了。
事实上,在用流的过程中,我们用到很多方法函数。比如上面的limit方法,filter方法等。这个定义为流操作。但是不管是什么操作,你必须要有一个数据源吧。总结如下:
数据源:用于生成流的数据,比如集合。
流操作:类似于limit方法,filter方法。
流还有一种特点——部分流操作是没有执行的。一般都是在collect函数执行的时候,才开始执行个个函数。所以我们可以细分一下流操作:
数据源:用于生成流的数据,比如集合。
中间操作:类似于limit方法,filter方法。这些操作做变了一个操作链,有一点流水线的概念。
终端操作:执行上面的操作链。比如collect函数。
从上面的讲解我们就可以感觉流好像是先收集相关的目标操作,什么意思呢?就是先把要做的事情计划一下,最后一声令下执行。而下这个命令是collect函数。这一点跟.NET的Linq是很像的。同时记得他只能执行一次。也就是说这个流执行一次之后,就不可能在用了。
笔者列一下以前的用到的函数
复制代码
forEach:终端
collect:终端
count:终端
limit:中间
filter:中间
map:中间
sorted:中间
复制代码
到目前为止我们用到的流都是通过集合来建一个流。笔者对此从来没有讲过。现在笔者来讲些构建流的方式。
在stream库里面为我们提供了这样子一个方法——Stream.of
复制代码
package com.aomi;
import java.util.Optional;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Stream stream = Stream.of("I", "am", "aomi");
Optional<String> firstWord = stream.findFirst();
if(firstWord.isPresent())
{
System.out.println("第一个字:"+firstWord.get());
}
}
}
复制代码
运行结果:
去看一下of方法的代码。如下
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
说明我们可能指定一个类型来建一个流。上面可以修改为
Stream<String> stream = Stream.of("I", "am", "aomi");
findFirst函数用于表示返回第一个值。那就是可能数据源是一个空呢?所以他有可以会返回null。所以就是用一个叫Optional类的表示可以为空。这样子我们就可以用Optional类的方法进一步做安全性的操作。比如判断有没有值(isPresent())
笔者想要建一个int类型的数组流玩玩。为了方便笔者便试给一下上面的代码。却发现报错了。
如果我把int改为Integer呢?没有问题了。所以注意要用引用类型的。int类型对应为Integer类型。
复制代码
1 package com.aomi;
2
3 import java.util.Optional;
4 import java.util.stream.Stream;
5
6 public class Main {
7
8 public static void main(String[www.shengyunyule.cn] args) {
9 // TODO Auto-generated method stub
10
11 Stream<Integer> stream = Stream.of(1, 2, 9);
12
13 Optional<Integer> firstWord = stream.findFirst();
14
15 if(firstWord.isPresent(www.gaozhuoyiqi.com))
16 {
17 System.out.println("第一个字:"+firstWord.get());
18 }
19
20 }
21
22 }
复制代码
运行结果:
那想要用int类型呢?什么办呢?改改
复制代码
1 package com.aomi;
2
3 import java.util.OptionalInt;
4 import java.util.stream.IntStream;
5
6 public class Main {
7
8 public static void main(String[] args) {
9 // TODO Auto-generated method stub
10
11 IntStream stream = IntStream.of(1, 2, 9);
12
13 OptionalInt firstWord = stream.findFirst();
14
15 if(firstWord.isPresent())
16 {
17 System.out.println("第一个字:"+firstWord.getAsInt());
18 }
19
20 }
21
22 }
复制代码
运行结果:
我们以上面的例子来一个猜测:是不是Double类型,只要修改为DoubleStream就行呢?试试。
复制代码
1 package com.aomi;
2
3 import java.util.OptionalDouble;
4 import java.util.stream.DoubleStream;
5
6 public class Main {
7
8 public static void main(String[www.hengtongyoule.com] args) {
9 // TODO Auto-generated method stub
10
11 DoubleStream stream = DoubleStream.of(1.3, 2.3, 9.5);
12
13 OptionalDouble firstWord = stream.findFirst();
14
15 if(firstWord.isPresent())
16 {
17 System.out.println("第一个字:"+firstWord.getAsDouble());
18 }
19
20 }
21
22 }
复制代码
运行结果:
结果很明显,我们的猜测是对的。所以见意如果你操作的流是一个int或是double的话,请进可能的用XxxStream 来建流。这样子在流的过程中不用进行拆装和封装了。必竟这是要性能的。在看一下如果数据源是一个数组的情况我们如何生成流呢?
复制代码
1 public static Collector<CharSequence, ?, String> joining(CharSequence delimiter,
2 CharSequence prefix,
3 CharSequence suffix) {
4 return new CollectorImpl<www.yongshiyule178.com>(
5 () -> new StringJoiner(delimiter, prefix, suffix),
6 StringJoiner::add, StringJoiner::merge,
7 StringJoiner::toString, CH_NOID);
8 }
复制代码
在看一个叫toList函数的代码。
复制代码
1 public static <T>
2 Collector<T, ?, List<T>> toList(www.gouyiflb.cn) {
3 return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
4 (left, right) -> { left.addAll(right); return left; },
5 CH_ID);
6 }
复制代码
我们发现他会共同的返回一个Collector类型。从上面我们就可以知道他的任务就是用去处理最后数据。我们把他定为收集器。让我们看一下收集器的接口代码吧;
复制代码
1 public interface Collector<T, A, R> {
2
3 Supplier<A> supplier();
4
5 BiConsumer<A, T> accumulator();
6
7 BinaryOperator<A> combiner();
8
9 Function<A, R> finisher();
10
11 Set<Characteristics> characteristics();
12 }
复制代码
光看前面四个方法是不是有一点熟悉的感觉。想要说明这个五个方法的作用。就必须明白一个概念——并行归约。前面笔者讲过流是一个内部迭代,也说Stream库为我们做一个很多优化的事情。其中一个就是并行。他用到了JAVA 7引入的功能——分支/合并框架。也就是说流会以递归的方式拆分成很多子流,然后子流可以并行执行。最后在俩俩的子流的结果合并成一个最终结果。而这俩俩合并的行为就叫归约 。如图下。引用于《JAVA8实战》
我们必须根据图上的意思来走。子流的图里面会调用到Collector类的三个方法。
supplier方法:用创建数据存储的地方。
accumulator方法:用于子流执行过程的迭代工作。即是遍历每一项都会执行。所以可以这里做一些工作。
finisher方法:返回最后的结果,你可以在这里进一步处理结果。
每一个子流结束这之后,就是俩俩合并。这个时候就要看流的机制图了。
combiner方法:会传入每一个子流的结果过来,我们就可以在这里在做一些工作。
finisher方法:返回最后的结果。同上面子流的一样子。
好像没有characteristics什么事情。不是这样子的。这个方法是用来说明当前这个流具备哪些优化。这样子执行流的时候,就可以很清楚的知道要以什么样子的方式执行了。比如并行。
他是一个enum类。值如下
UNORDERED:这个表示执行过程中结果不受归约和遍历的影响
CONCURRENT:表示可以多个线和调用accumulator方法。并且可以执行并行。当然前无序数据的才并行。除非收集器标了UNORDERED。
IDENTITY_FINISH:表示这是一个恒等函数,就是做了结果也一样子。不用做了可以跳过了。
由了上面的讲说明,我们在来写一个自己的收集器吧——去除相同的单词
DistinctWordCollector类:
复制代码
1 package com.aomi;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.EnumSet;
6 import java.util.List;
7 import java.util.Set;
8 import java.util.function.BiConsumer;
9 import java.util.function.BinaryOperator;
10 import java.util.function.Function;
11 import java.util.function.Supplier;
12 import java.util.stream.Collector;
13
14 public class DistinctWordCollector implements Collector<String, List<String>, List<String>> {
15
16 @Override
17 public Supplier<List<String>> supplier() {
18 // TODO Auto-generated method stub
19 return () -> new ArrayList<String>();
20 }
21
22 /**
23 * 子流的处理项的过程
24 */
25 @Override
26 public BiConsumer<List<String>, String> accumulator() {
27 // TODO Auto-generated method stub
28 return (List<String> src, String val) -> {
29
30 if (!src.contains(val)) {
31 src.add(val);
32 }
33 };
34 }
35
36 /**
37 * 俩俩并合的执行函数
38 */
39 @Override
40 public BinaryOperator<List<String>> combiner() {
41 // TODO Auto-generated method stub
42 return (List<String> src1, List<String> src2) -> {
43 for (String val www.yunshenpt.com: src2) {
44 if (!src1.contains(val)) {
45 src1.add(val);
46 }
47 }
48 return src1;
49 };
50 }
51
52 @Override
53 public Function<List<String>, List<String>> finisher() {
54 // TODO Auto-generated method stub
55 return Function.identity();
56 }
57
58 @Override
59 public Set<Characteristics> characteristics() {
60 // TODO Auto-generated method stub
61 return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.CONCURRENT));
SpringBoot 从application.yml中通过@Value读取不到属性值的更多相关文章
- springboot获取application.yml中的配置信息
HelloController.java package com.springbootweb.demo.controller; import com.springbootweb.demo.entity ...
- PHP中使用DOM读取解析XML属性值一例
先看XML文件结构,与常见的文件略有不同,数据并不是用闭合标签保存的,而是直接保存在属性值中. <?xml version="1.0" encoding="utf- ...
- springboot在application.yml中使用了context-path属性导致静态资源法加载,如不能引入vue.js,jquery.js,css等等
在springBoot配置中加入上下文路径 server.context-path=/csdn js,img等静态文件无法加载,出现404的问题 <script type="text/ ...
- SpringBoot获得application.properties中数据的几种方式
转:https://blog.csdn.net/qq_27298687/article/details/79033102 SpringBoot获得application.properties中数据的几 ...
- Objective-C中变量采用@property的各个属性值的含义
我们在OC中定义变量,可以自己来定义变量的setter方法来设置变量值,用getter方法来获取变量值.但是当变量数量增多时,还采用手动添加setter/getter方法来操作变量,就会使得程序代码量 ...
- 清除bean中所有非基本数据类型的属性值
利用beanutils清除javabean中所有非基本数据类型的属性值: import com.google.gson.Gson; import lombok.Data; import org.apa ...
- 【Java】SpringBoot 中从application.yml中获取自定义常量
由于这里我想通过java连接linux,connection连接需要host.port.username.password及其他路径等等.不想每次修改的时候都去改源文件,所以想写在applicatio ...
- SpringBoot中logback.xml使用application.yml中属性
教你如何使用 springProfile 与 springProperty 让你的logback.xml 配置显得更有逼格,当别人还在苦苦挣扎弄logback-{profile}.xml的时候 你一个 ...
- Springboot 配置 application.yml 连接MySQL数据库
1.在pom.xml的<dependencies></dependencies>标签中中加入以下依赖 <dependency> <groupId>org ...
随机推荐
- 闽江学院软件学院2016级JAVA构建之法-学生自学兴趣小组招募通知
为提升我2016级学生提升JAVA软件开发学习氛围,鼓励更多同学通过自学.团队学习.在线(社区)学习等方式学习并掌握JAVA课程,尤其是鼓励同学们通过微软中国邹欣老师所倡导的"构建之法&qu ...
- NFV论文集(三)综述
一 文章名称:Dependability of the NFV Orchestrator: State of the Art and Research Challenges 发表时间:2018 期刊来 ...
- python三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...
- YCSB报": No such file or directory"异常
异常信息如下: 文件路径.权限都没有问题. 上网遍寻无果,安装流程与官网一致,开始怀疑是环境问题,后来用别人能用的YCSB复制到本地,却能正常运行. 后来修改了ycsb文件,加了个空格,保存退出,再运 ...
- Spring Mvc和Spring Boot读取Profile方式
spring boot java代码中获取spring.profiles.active - u013042707的专栏 - CSDN博客https://blog.csdn.net/u013042707 ...
- FAIL - Deploy Upload Failed, Exception: [org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (112503036) exceeds the configured
Message: FAIL - Deploy Upload Failed, Exception: [org.apache.tomcat.util.http.fileupload.FileUpload ...
- PHP中友好的处理方式
在使用PHP进行开发的时候,由于PHP是弱类型语言的特性,所以,偶尔会遇到一些意想不到的错误.规范我们的编程就变得尤为重要了.下面总结一下,我日常开发中的一些经验,可能有些地方不妥,还请多多斧正,指教 ...
- Laravel从入门到精通
1. Laravel框架的下载安装 例如: 在D:\test\laravel目录下新建一个目录为test_laravel 第一步,下载laravel框架 在D:\test\laravel\test_l ...
- python time模块介绍(日期格式化 时间戳)
import time # 1.time.time() 用于获取当前时间的时间戳, ticks = time.time() print(ticks) # 1545617668.8195682 浮点数 ...
- sed命令参数之-r -i
对于初学linux的朋友来说,能记住命令附带的一大帮参数就以及非常不容易了.好不容易把该用的参数都想全了.sed -irns 后面一大片脚本 ,一执行出错了 what!!!! 创建一下测试环境 hea ...