Lambda Optional代替if-else
前言函数式的编程可以极大的简化逻辑代码的编写,虽然是一种语法糖,但是好用就是好用。Optional 这个功能可以用来防止null值给程序带来的异常,提供的API也可以用来简化逻辑代码的编码,简化if-else的编写。
写法比较常规代码写法一般写一个业务逻辑时,业务代码需要加很多判断,保证程序的健状性。
12345678910111213public void test() { User user = userService.getUser(); if (user != null) { String userName = user.getUserName(); if (userName != null) { return userName.toUpperCase(); } else { return null; } } else { return null; }}
改进后可以看到,改进后的写法,判空这种操作,直接交给Optiona ...
springboot 发送邮件
最近重写一个邮件服务来给告警业服务用,做成一个内置的应用。直接使用 spring 的 javamail 来实现。公司使用腾讯企业邮箱。这个例子正常使用,可以直接套上使用。
邮件配置以下配置方式二选一
代码方式
yml方式
代码方式1234567891011121314151617181920212223242526272829303132333435363738394041424344454647package com.liukai.springmail.send;import org.springframework.beans.factory.annotation.Configurable;import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;import org.springframework.boot.autocon ...
java 解决父构造器中拿到对象
这两天被问到一个有意思的问题,就是如果在构造器中拿到匿名对象。这个问题有意思在,直觉上是可以通过外部放一个成员变量去接,然后后续就可以使用了,但实际不行。
问题复现下面这个是构造器,当通过 supper 去调用父类构造器。由于问题出现在Spring项目当中,所以我复现的例子也基于Spring重新搭了一个项目来复现这个过程,代码放github上。
复现demo:
12345678910111213package com.test;import org.springframework.beans.factory.annotation.Autowired;public class TransactionCache extends RevokingDB { @Autowired public TransactionCache(String dbName) { // 其他代码不能在 supper 之前,但是又要拿到 TxCacheDB,不能再new一次,否则会初始化两次TxCacheDB。 super(new TxCacheDB(dbName)); // ...
Lambda Optional使用
简述Optional 针对空指处理而设计的类型。Java 8借鉴了Scala和Haskell,提供了一个新的Optional模板,可以用它来封装可能为空的引用。这是一个可以为null的容器对象。使用 Optional 的好处是可以以一种专门针对null的处理方式,来避免值可能存在 null 导致出现的程序异常。你可以理解为:处理null,就是你的业务。在实际使用过程中,你会发现 Optional 的灵活性有时候会让你想用在任何可能出现null的地方,不过凡事都有套路可循,只要清楚利弊就知道该如何选择。
从两个方面说一下 Optional
常用API
项目使用套路
只讲 API 不讲使用套路的文章都是耍流氓。
API说明先看一下常用API,后面再讲实际使用场景。
构建API: 构建Optional对象:of()、ofNullable()、empty()
获取API: 获取Optional对象包装的值:get()、orElse()、orElseGet()、orElseThrow()
判断API:对Optional对象里包装的值做一些逻辑判断:isPresent()、ifPresent ...
静态资源配置的问题
spring boot 的项目是将静态资源打包到.jar 的文件包中, 项目中有碰到需要使用外部静态资源的情况,使用外部资源的一直老出问题,查了google 后发现是指定的方式不对。
静态资源配置将 resource/static 进行映射,springboot 默认优先级:
/META-INF/resources//resources//static//public/
spring 属性合配 resources 配置1.本项目包含路径:
12345spring:mvc: static-path-pattern: /lateresources: static-locations: classpath:/templates/dist/
这两天遇到的坑
2.指定项目外的磁盘路径如果要映射本地磁盘路径,可以使用,注意必须得有 file:, 注意必须得有file:,注意必须得有file: 否则 404, 重要事情说三遍。
12345spring:mvc: static-path-pattern: /lateresources: static-locations: fil ...
springboot 注解实现日志切面
项目中很多时候需要去打印方法入参和出参的日志,有助于排查错误。注解需要操作简单。常用的方式之一就是使用切面来切日志。
步骤:
定义自定义注解
编写自定义注解的切面方法
使用注解在需要输出日志的方法上
1.自定义注解1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253/** * * controller 注解切面 * @author liukai * @data 2018/8/7 15:26. */@Target({ElementType.PARAMETER, ElementType.METHOD})//目标是方法@Retention(RetentionPolicy.RUNTIME)//注解会在class中存在,运行时可通过反射获取@Documented//文档生成时,该注解将被包含在javadoc中,可去掉@Inheritedpublic @interface ControllerLog { /** ...
Lambda01-Functional 函数式接口
Functional 为 lambda 方法提供一个接口
函数式接口Functional 的定义其实很简单:任何接口,如果只包含 唯一一个抽象方法,那么它就是一个 Functional Interface ,函数式接口?这注解名字好。为了让编译器帮助我们确保一个接口满足 Functional Interface 的要求(也就是说有且仅有一个抽象方法),Java8提供了@FunctionalInterface注解。
先学习函数式接,才能理解学习 Lambda 表达式。
有什么用白话:用来为函数式编程提供接口。就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。函数式接口可以被隐式转换为 lambda 表达式。
简单示例写一个最简单的例子做为入门参考,看不懂不要紧,这个只是一个例子。
声明一个无参的接口声明一个无参函数式接口,为 lambda 提供一个接口。在接口上添加@Functional那么这个接口就是一个函数式接口
1234@FunctionalInterfacepublic interfaceMyFunctional { public abstract ...
使用freemarker页面静态化
公司使用 vue + ngixn 前后端分离架构,重构一套新的静态化的门户网站。后台管理系统为动态页面。使用 freemarker 进行页面静态化的处理,生成静态化页在。前后分离的页面,静态图片需要使用 nginx 进行路径转换。UEditor 上传到本地的图片,没有使用文件管理系统,直接存放到服务器本地,需要 nginx 进行路径转换。
使用原理:1.freemarker 将数据填充入 ftl 模板中,再由 freemarker 生成静态页面2.vue 获取静态页面进行数据展示
1.工具类
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960import freemarker.template.Configuration;import freemarker.template.Template;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import ...
什么是上下文context
上下文(背景/语境) context是当前运行程序的环境。网上各种不可说,模糊不清,但是一个概念的提出肯定有最初的含义。
总结上下文可以理解成:
上下文指由代码已运行的程序环境,不是指代码。
一组状态,这个好理解,取 spring cloud 的官方文档的例子:
一个Spring Cloud应用程序通过创建一个"引导"上下文来进行操作,这个上下文是主应用程序的父上下文。引导上下文使用与主应用程序上下文不同的外部配置约定,因此使用bootstrap.yml application.yml(或.properties)代替引导和主上下文的外部配置。这里所谓的 引导上下文 就是一组状态,实际就是一个保存配置的大对象,换个角度理就是环境。
环境背景每一段程序都有很多外部变量。只有像Add这种简单的函数才是没有外部变量的。一旦你的一段程序有了外部变量,这段程序就不完整,不能独立运行。你为了使他们运行,就要给所有的外部变量一个一个写一些值进去。这些值的集合就叫上下文。
摘自知乎
和其他传入对象参数没什么区别。但是通常使用Context来描述有几个特点:被传入Context的 ...
spring boot 使用maven打jar包配置
使用 ide 进行开发时,直接在ide上启动即可,如果要放到服务器上进行使用,就必须打成jar包,这里使用 maven 的打包插件进行打包。注意 <mainClass>com.devops.WebApplication</mainClass> 这行要改成你的启动类。
1234567891011121314151617181920212223242526272829303132<build> <finalName>devops-web</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> ...