小工具推荐(random-beans/MapStruct/Checker Framework/vjtools)

栏目: Java · 发布时间: 6年前

内容简介:地址:随机生成Pojo对象,填充字段,UnitTest利器,牛逼之处在于1) 能处理所有常见类型,包括枚举。

1. Mock Bean对象生成工具:random-beans

2. Bean属性复制:MapStruct

3. Java代码检查工具:Checker Framework

4. java相关的 工具 库:vjtools(唯品会出品)

小工具推荐

  1. Mock Bean对象生成工具:random-beans
  2. Bean属性复制:MapStruct
  3. Java代码检查工具:Checker Framework
  4. java相关的工具库:vjtools(唯品会出品)

1. Mock Bean对象生成工具:random-beans

地址: https://github.com/benas/random-beans

随机生成Pojo对象,填充字段,UnitTest利器,牛逼之处在于

1) 能处理所有常见类型,包括枚举。

2) 能处理级联对象结构,Bean里嵌套Bean这种。

简单示例如下,90%的情况下都够用,再也不用new一个Bean,然后一顿Set属性了:

Person person =EnhancedRandom.random(Person.class); // one pojo
Stream<Person> persons = EnhancedRandom.randomStreamOf(10, Person.class); //  batch 10 pojos

使用EnhancedRandom实现自定义规则的bean填充:

EnhancedRandom enhancedRandom = EnhancedRandomBuilder.aNewEnhancedRandom();
Person person = enhancedRandom.nextObject(Person.class);
EnhancedRandom random = EnhancedRandomBuilder.aNewEnhancedRandomBuilder()
  .seed(123L)
  .objectPoolSize(100)
  .randomizationDepth(3)
  .charset(forName("UTF-8"))
  .timeRange(nine, five)
  .dateRange(today, tomorrow)
  .stringLengthRange(5, 50)
  .collectionSizeRange(1, 10)
  .scanClasspathForConcreteTypes(true)
  .overrideDefaultInitialization(false)
  .build();

更高级的定制,精确控制字段:

EnhancedRandom enhancedRandom = EnhancedRandomBuilder.aNewEnhancedRandomBuilder()
  .randomize(String.class, (Randomizer<String>) () -> "foo")
  .exclude(field().named("age").ofType(Integer.class).inClass(Person.class).get())
  .build();
Person person = enhancedRandom.nextObject(Person.class);

2. Bean属性复制:MapStruct

地址: http://mapstruct.org/

牛逼之处在于可以处理不同名称的属性映射,也可以处理级联关系。

参考: https://blog.csdn.net/lx_yoyo/article/details/75061614

...
<properties>
   <!-- <org.mapstruct.version>1.1.0.Beta1</org.mapstruct.version>-->
     <org.mapstruct.version>1.1.0.Final</org.mapstruct.version>
</properties>
...
<dependencies>
   <dependency>
       <groupId>org.mapstruct</groupId>
       <artifactId>mapstruct-jdk8</artifactId>
       <version>${org.mapstruct.version}</version>
   </dependency>
    <dependency>
           <groupId>org.mapstruct</groupId>
           <artifactId>mapstruct-processor</artifactId>
           <version>${org.mapstruct.version}</version>
       </dependency>
  <!-- <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>-->
       </dependency>
</dependencies>
...
<build>
   <plugins>
       <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>3.5.1</version>
           <configuration>
               <source>1.8</source>
               <target>1.8</target>
               <annotationProcessorPaths>
                   <path>
                       <groupId>org.mapstruct</groupId>
                       <artifactId>mapstruct-processor</artifactId>
                       <version>${org.mapstruct.version}</version>
                   </path>
               </annotationProcessorPaths>
           </configuration>
       </plugin>
   </plugins></build>
...

其核心原理是通过@Mapper接口和@Mapping映射关系定义,自动生成一个MapperImpl实现类,在这个实现类里做生成好了setter属性值的代码。

@Mapper注解标记这个接口作为一个映射接口,并且是编译时MapStruct处理器的入口。

@Mapping解决源对象和目标对象中,属性名字不同的情况。

Mappers.getMapper自动生成的接口的实现可以通过Mapper的class对象获取,从而让客户端可以访问Mapper接口的实现。

@Mapper
public interface PeopleMapper {
   PeopleMapper INSTANCE = Mappers.getMapper(PeopleMapper.class);
   /**
    * PO转DTO
    *
    * @param entity PO
    * @return DTO
    */
   @Mapping(target = "phoneNumber", source = "callNumber")
   @Mapping(target = "user.name", source = "name")
   @Mapping(target = "user.age", source = "age")
   PeopleDTO entityToDTO(PeopleEntity entity);
   /**
    * DTO转PO
    *
    * @param peopleDTO DTO
    * @param entity PO
    */
   @Mapping(target = "callNumber", source = "phoneNumber")
   @Mapping(target = "name", source = "user.name")
   @Mapping(target = "age", source = "user.age")
   void updateEntityFromDto(PeopleDTO peopleDTO, @MappingTarget PeopleEntity entity);
}

3. Java代码检查工具:Checker Framework

地址: https://checkerframework.org/

源码: https://github.com/typetools/checker-framework/

内置了几十种检查规则,也可以方便的自定义检查规则。

例如空指针检查:

public class NullnessExample {
   public static void main(String[] args) {
       Object myObject = null;
       System.out.println(myObject.toString());
   }
}

执行:

$ javacheck -processor org.checkerframework.checker.nullness.NullnessChecker NullnessExample.java

我们将看到:

NullnessExample.java:9: error: [dereference.of.nullable] dereference of possibly-null reference myObject
       System.out.println(myObject.toString());
                          ^
1 error

4. java相关的工具库:vjtools(唯品会出品)

Java开发相关

  • standard Java开发手册
  • code formatter IDE格式化模板
  • sonar rule Sonar规则定制示例
  • vjkit 关于文本,集合,并发等基础功能的核心类库
  • vjstar 关于后端应用的性能、可用性的最佳实践

Java开发相关

  • vjtop 观察JVM进程指标及其繁忙线程
  • vjmap JMAP的分代打印版
  • vjdump 线上紧急收集JVM数据脚本
  • vjmxcli JMX 查看工具
    以vjtop为例:找出CPU最繁忙的线程
// 按时间区间内,线程占用的CPU排序,默认显示前10的线程,默认每10秒打印一次
./vjtop.sh <PID>
// 按线程从启动以来的总占用CPU来排序
./vjtop.sh --totalcpu <PID>
// 按时间区间内,线程占用的SYS CPU排序
./vjtop.sh --syscpu <PID>
// 按线程从启动以来的总SYS CPU排序
./vjtop.sh --totalsyscpu <PID>

输出示例:

PID: 191082 - 17:43:12 JVM: 1.7.0_79 USER: calvin UPTIME: 2d02h
PROCESS: 685.00% cpu(28.54% of 24 core), 787 thread
MEMORY: 6626m rss, 6711m peak, 0m swap | DISK: 0B read, 13mB write
THREAD: 756 live, 749 daemon, 1212 peak, 0 new | CLASS: 15176 loaded, 161 unloaded, 0 new
HEAP: 630m/1638m eden, 5m/204m sur, 339m/2048m old
NON-HEAP: 80m/256m/512m perm, 13m/13m/240m codeCache
OFF-HEAP: 0m/0m direct(max=2048m), 0m/0m map(count=0), 756m threadStack
GC: 6/66ms/11ms ygc, 0/0ms fgc | SAFE-POINT: 6 count, 66ms time, 5ms syncTime
   TID NAME STATE CPU SYSCPU TOTAL TOLSYS
    23 AsyncAppender-Worker-ACCESSFILE-ASYNC WAITING 23.56% 6.68% 2.73% 0.72%
   560 OSP-Server-Worker-4-5 RUNNABLE 22.58% 10.67% 1.08% 0.48%
  9218 OSP-Server-Worker-4-14 RUNNABLE 22.37% 11.45% 0.84% 0.40%
  8290 OSP-Server-Worker-4-10 RUNNABLE 22.36% 11.24% 0.88% 0.41%
  8425 OSP-Server-Worker-4-12 RUNNABLE 22.24% 10.72% 0.98% 0.47%
  8132 OSP-Server-Worker-4-9 RUNNABLE 22.00% 10.68% 0.90% 0.42%
  8291 OSP-Server-Worker-4-11 RUNNABLE 21.80% 10.09% 0.89% 0.41%
  8131 OSP-Server-Worker-4-8 RUNNABLE 21.68% 9.77% 0.93% 0.44%
  9219 OSP-Server-Worker-4-15 RUNNABLE 21.56% 10.43% 0.90% 0.41%
  8426 OSP-Server-Worker-4-13 RUNNABLE 21.35% 10.42% 0.66% 0.31%
Total : 668.56% cpu(user=473.25%, sys=195.31%) by 526 atcive threads(which cpu>0.05%)
Setting: top 10 threads order by CPU, flush every 10s
Input command (h for help):

进程区数据解释:

PROCESS: thread: 进程的操作系统线程数, cxtsw为主动与被动的线程上下文切换数
MEMORY: rss 为 Resident Set Size, 进程实际占用的物理内存; peak为最峰值的rss; swap为进程被交换到磁盘的虚拟内存。
DISK: 真正达到物理存储层的读/写的速度。
THREAD: Java线程数, active为当前线程数, daemon为active线程中的daemon线程数, new为刷新周期内新创建的线程数。
CLASS: loaded为当前加载的类数量,unloaded为总卸载掉的类数量,new为刷新周期内新加载的类数量。
HEAP: 1.0.3版开始每一项有三个数字, 分别为1.当前使用内存, 2.当前已申请内存, 3.最大内存; 如果后两个数字相同时则合并。
sur: 当前存活区的大小,注意实际有from, to 两个存活区。
NON-HEAP: 数字含义同HEAP
codeCache: JIT编译的二进制代码的存放区,满后将不能编译新的代码。
direct: 堆外内存,三个数字含义同HEAP, 未显式设置最大内存时,约等于堆内存大小。注意新版Netty不经过JDK API所分配的堆外内存未在此统计。
map: 映射文件内存,三个数字分别为1. map数量,2.当前使用内存,3.当前已申请内存,没有最大值数据。
threadStack: Java线程所占的栈内存总和,但不包含VM线程。(since 1.0.3)
ygc: YoungGC, 三个数字分别为次数/总停顿时间/平均停顿时间
fgc: OldGC + FullGC, 两个数字分别为次数/总执行时间,注意此时间仅为执行时间,非JVM停顿时间。
SAFE-POINT: PerfData开启时可用,JVM真正的停顿次数及停顿时间,以及等待所有线程进入安全点所消耗的时间。

线程区数据解释:

CPU: 线程在打印间隔内使用的CPU百分比(按单个核计算)
SYSCPU: 线程在打印间隔内使用的SYS CPU百分比(按单个核计算)
TOTAL: 从进程启动到现在,线程的总CPU时间/进程的总CPU时间的百分比
TOLSYS: 从进程启动到现在,线程的总SYS CPU时间/进程的总CPU时间的百分比

底部数据解释:

如果该线程的平均使用CPU少于单核的0.1%,这条线程将不参与 排序 显示,减少消耗。

JVM优化参数

JVM参数的精髓都在这里,而且是以实例脚本的形式实现的,直接可以拿来用:

https://github.com/vipshop/vjtools/blob/master/vjstar/src/main/script/jvm-options/jvm-options.sh

脚本片段如下:

# 启动时预申请内存
MEM_OPTS="$MEM_OPTS -XX:+AlwaysPreTouch"
# 如果线程数较多,函数的递归较少,线程栈内存可以调小节约内存,默认1M。
#MEM_OPTS="$MEM_OPTS -Xss256k"
# 堆外内存的最大值默认约等于堆大小,可以显式将其设小,获得一个比较清晰的内存总量预估
#MEM_OPTS="$MEM_OPTS -XX:MaxDirectMemorySize=2g"
# 根据JMX/VJTop的观察,调整二进制代码区大小避免满了之后不能再JIT,JDK7/8,是否打开多层编译的默认值都不一样
#MEM_OPTS="$MEM_OPTS -XX:ReservedCodeCacheSize=240M"
## GC Options##
GC_OPTS="-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly"
# System.gc() 使用CMS算法
GC_OPTS="$GC_OPTS -XX:+ExplicitGCInvokesConcurrent"
# CMS中的下列阶段并发执行
GC_OPTS="$GC_OPTS -XX:+ParallelRefProcEnabled -XX:+CMSParallelInitialMarkEnabled"
# 根据应用的对象生命周期设定,减少事实上的老生代对象在新生代停留时间,加快YGC速度
GC_OPTS="$GC_OPTS -XX:MaxTenuringThreshold=3"
# 如果OldGen较大,加大YGC时扫描OldGen关联的卡片,加快YGC速度,默认值256较低
GC_OPTS="$GC_OPTS -XX:+UnlockDiagnosticVMOptions -XX:ParGCCardsPerStrideChunk=1024"
# 如果JVM并不独占机器,机器上有其他较繁忙的进程在运行,将GC线程数设置得比默认值(CPU核数*5/8 )更低以减少竞争,反而会大大加快YGC速度。
# 另建议CMS GC线程数简单改为YGC线程数一半.
#GC_OPTS="$GC_OPTS -XX:ParallelGCThreads=12 -XX:ConcGCThreads=6"
# 如果CMS GC时间很长,并且明显受新生代存活对象数量影响时打开,但会导致每次CMS GC与一次YGC连在一起执行,加大了事实上JVM停顿的时间。
#GC_OPTS="$GC_OPTS -XX:+CMSScavengeBeforeRemark"
# 如果永久代使用不会增长,关闭CMS时ClassUnloading,降低CMS GC时出现缓慢的几率
#if [[ "$JAVA_VERSION" > "1.8" ]]; then    
# GC_OPTS="$GC_OPTS -XX:-CMSClassUnloadingEnabled"
#fi

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Landing Page Optimization

Landing Page Optimization

Tim Ash / Wiley Publishing / 2008-1-29 / USD 29.99

在线阅读本书 How much money are you losing because of poor landing page design? In this comprehensive, step-by-step guide, you’ll learn all the skills necessary to dramatically improve your bottom li......一起来看看 《Landing Page Optimization》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

在线进制转换器
在线进制转换器

各进制数互转换器

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具