拒绝重复发明轮子,向大师致敬

Posted by NotGeek on January 18, 2018

拒绝重复发明轮子,向大师们致敬

7 月 18 号,开讲

主要议程

  • Java API 扩展
  • 配置管理
  • Web 特性

Java API 扩展

主要是 java 5 ~ Java 9

语言相关

java.lang 以及扩展

String 为什么 final , private final byte[] value; 为什么要 final ,

主要是因为它不想被继承被覆盖。继承可以覆盖,会有多态行为。会产生一些不确定因素,String 的不变性就会发生改变。

java.lang.CharSequence @since 1.4

字符串通常会有长度的

字符串长度
  • 场景
    • 非空
      • 完全空字符串
      • 空格、换行
    • 长度判断
  • 框架
    • Apache Commons lang (目前已经 3.x)
      • 2.x
        • org.apache.commons.lang
      • 3.x
        • org.apache.commons.lang3

不同的方法,避免类冲突。

String

  • #subString

charSequence

  • #subSequence 更底层

  • #toString 返回String

org.apache.commons.lang3.StringUtils

  • #isNumeric
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class StringDemo {
    public static void main(String[] args) {
        Stream.of("as", "sdf", "12", "34", "23", "", null)
                .filter(Objects::isNull) // 方法是从 JAVA 8 开始的, Objects 是从 Java 7 开始的
                .filter(StringUtils::isNoneBlank)  // apache Commons langs
                .filter(StringUtils::isNumeric)
                .forEach(System.out::println);

        Stream.of("as", "sdf", "12", "34", "23", "", null)
                .filter(org.springframework.util.StringUtils::hasText)  // Spring framework
                .filter(StringUtils::isNumeric)
                .forEach(System.out::println);
    }
}

集合相关

  • 场景
    • 非空
    • 大小判断

注释写在上边是业务场景,写在后边是补充注释。

Spring 也有很多东西不符合国际公约

  • 国际规约不允许以 I 开头为接口,

    ​ 但是 Thymeleaf Eclipse 很多软件都是的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.darian.util;

import com.fasterxml.jackson.databind.ser.std.MapSerializer;
import org.apache.commons.collections.CollectionUtils;

import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class CollectionDemo {
    public static void main(String[] args) {
        List<String> stringList = List.of("2", "3", "4");// since 9
        // java.lang.UnsupportedOperationException
        //stringList.add("4");   // ImmutableCollections 不变的

        System.out.println(CollectionUtils.isNotEmpty(stringList)); // apache Commons Collections
        System.out.println(CollectionUtils.isFull(stringList));  // apache

        System.out.println(org.springframework.util.CollectionUtils.isEmpty(stringList)); // Spring framework
        Map<String, String> maps = Map.of("A","A","c","c");
        System.out.println(org.springframework.util.CollectionUtils.isEmpty(maps));

        // 使用场景有关系
        // Spring Framework < Apache commons lang(<=4 的时候依赖)
        // Spring Framework <5  => Apache commons logging(不再需要了)
        // Spring Frameowrk >=5  -> Spring JCL
        // Apache Commons Lang 2.4 & 2.6 会有一些不兼容
    }

    {
        // Effective Java II   都是不变的对象
        EnumSet<TimeUnit> timeUnits =
                EnumSet.of(TimeUnit.DAYS, TimeUnit.HOURS);
    }
}

使用场景有关系
  • Spring Framework < Apache commons lang(<=4 的时候依赖)
  • Spring Framework <5 => Apache commons logging(不再需要了)
  • Spring Frameowrk >=5 -> Spring JCL
  • Apache Commons Lang 2.4 & 2.6 会有一些不兼容

I/O相关

org.springframework.util.StreamUtils

org.springframework.util.StreamUtils#copyToString

配置管理

Java 系统属性

java.lang.System#getProperty(java.lang.String)

java.lang.System#getProperties

Java 程序参数

-Dfile.encoding=UTF-8

等价于 System.setProperty("file.encoding","UTF-8")

参数解析

Spring Boot 启动参数: --server.port=9090

Spring :

org.springframework.core.env.SimpleCommandLineArgsParser

Spring @TestPropertySource#properties

@TestPropertySource#locations

同一个 @TestPropertySource 有两个不同的优先级。

Java 配置文件

Environment 也是 Spring 中的,

就是重复发明轮子,

Apache commons configuration

  • JNDI
  • JDBC Datasource
  • System properties
  • ……

在 Spring Boot 里边都有

自古文人都是贼,相互的抄袭

Spring Demo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

@SpringJUnitConfig
@TestPropertySource(properties = {"name = darian", "age=32"})
public class SpringPropertyTest {

    @Autowired
    private Environment environment;

    @Test
    public void test() {
        System.out.println("name:" + environment.getProperty("name"));
        System.out.println("age:" + environment.getProperty("age",Integer.class));
    }
}
apache
1
2
3
4
5
6
7
8
9
public class ConfigPropertiesDemo {
    public static void main(String[] args) throws ConfigurationException {

        URL resourceURL = Thread.currentThread().getContextClassLoader()
                .getResource("application.properties");
        Configuration configuration = new PropertiesConfiguration(resourceURL);
        System.out.println(configuration.getInt("age"));
    }
}

org.apache.commons.configuration.PropertyConverter

org.springframework.beans.SimpleTypeConverter

  • org.springframework.beans.TypeConverterSupport

org.springframework.beans.TypeConverter#convertIfNecessary(java.lang.Object, java.lang.Class<T>)

  • org.springframework.beans.TypeConverterSupport#doConvert
    • org.springframework.core.convert.support.DefaultConversionService

org.springframework.core.convert.support.StringToNumberConverterFactory.StringToNumber#convert

1
2
3
4
5
6
7
8
9
10
11
private static final class StringToNumber<T extends Number> implements Converter<String, T> {
    private final Class<T> targetType;

    public StringToNumber(Class<T> targetType) {
        this.targetType = targetType;
    }
    // 这个方法是转化类型的。
    public T convert(String source) {
        return source.isEmpty() ? null : NumberUtils.parseNumber(source, this.targetType);
    }
}

apache 1.1 2005

spring 3.0 2009 年

Apache Commons Configuration since 1.1 Propertycoverter

Spring framework since 3.0 Converter

Spring 重复发明轮子是一等的成功。

Web 特性

模板引擎

Apache Turbine Project

Turbine 涡轮。

Spring Cloud hystrix 里边有 搜集的功能。

Apache Turbine™ Web Application Framework

Apache Turbine™ is a servlet based framework that allows experienced Java developers to quickly build web applications. Turbine allows you to use personalize the web sites and to use user logins to restrict access to parts of your application.

Turbine is a matured and well established framework that is used as the base of many other projects (like e.g. the excellent Jetspeed 1 Portals framework.

Turbine is an excellent choice for developing applications that make use of a services-oriented architecture. Some of the functionality provided with Turbine includes a security management system (decoupled in Fulcrum Security), a scheduling service, XML-defined form validation server (Fulcrum Intake), and an XML-RPC service for web services. It is a simple task to create new services particular to your application.

The Turbine core is free of any dependency on a presentation layer technology. Both JavaServer Pages (JSP) and Velocity are supported inside Turbine. For developers already familiar with JSP, or have existing JSP tag libraries, Turbine offers support for the Sun standard. Velocity is the favorite view technology of most users of the Turbine framework; try it out and see if Velocity can help you develop your web applications faster and work more easily with non-programming designers.

Turbine is developed in an open, participatory environment and released under the Apache Software License. Turbine is intended to be a collaboration of the best-of-breed developers from around the world. We invite you to participate in this open development project. To learn more about getting involved, look at our “How to Help” pages.

SOA

Turbine: JSP + velocity 混用

Spring webMVC

org.springframework.web.servlet.ViewResolver

  • JSP
    • org.springframework.web.servlet.view.InternalResourceViewResolver
  • velocity
    • VelocityViewResolver

org.springframework.web.servlet.view.ContentNegotiatingViewResolver

1
2
3
4
// 把多个 viewResolver 放到一起。
public void setViewResolvers(List<ViewResolver> viewResolvers) {
    this.viewResolvers = viewResolvers;
}

org.springframework.web.servlet.DispatcherServlet#render 渲染方法

Spring 从创意上就是抄袭的。

REST 支持

Spring Web MVC / WebFlux
  • Annotation : @Controller@RequestMapping
  • 请求映射 @RequestMapping@GetMapping
  • producersconsumers

JAX-RS ( Java REST )

  • @GET@POST@PUT@DELETE@HEAD
  • @Produces@Consumes

JAX-RS 规范,

内容协商

https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation

rest 协议 有一个 自描述消息。 406 (Not Acceptable)

Principles of content negotiationSection

A specific document is called a resource. When a client wants to obtain it, it requests it using its URL. The server uses this URL to choose one of the variants it provides – each variant being called a representation – and returns this specific representation to the client. The overall resource, as well as each of the representations, have a specific URL. How a specific representation is chosen when the resource is called is determined by content negotiation and there are several ways of negotiating between the client and the server.

img

The determination of the best suited representation is made through one of two mechanisms:

  • Specific HTTP headers by the client (server-driven negotiation or proactive negotiation), which is the standard way of negotiating a specific kind of resource.
  • The 300 (Multiple Choices) or 406 (Not Acceptable) HTTP response codes by the server (agent-driven negotiation or reactive negotiation), that are used as fallback mechanisms.

Over the years, other content negotiation proposals, like transparent content negotiation and the Alternates header, have been proposed. They failed to get traction and got abandoned.

save

org.springframework.web.accept.HeaderContentNegotiationStrategy

客户端请求服务端的时候,请求头里边有 Accept: 告诉服务器,我可以接受你什么格式。

服务器根据你的内容,做一个预判。

根据 consumes 请求到不同的方法上边去。

Web 异步化

Web Reactive

自动装配

spring 4.x -> spring boot 1.x

spring 5.x -> spring boot 2.x

你要不要重复的发明轮子去做。