使用插件 aspectj-maven-plugin 织入 AspectJ AOP

昨天刚刚侍弄完 Spring 下基于自定义注解拦截方法调用,现在试下纯 AspectJ 的方式来打造,因为不是每一个项目都是 Spring。这次要推到 5 年前试验过用 javac 命令行编译的方式织入方面,见 AspectJ 基于自定义的方法注解来拦截方法,这次着重在用 aspectj-maven-plugin 插件的方法来织入 AspectJ 方面。

基本上代码还是昨天的,需求还是一样的:

被 @LogStartTime 注解的方法在进入该方法时记录当前时间在 ThreadLocal 中,并能根据 @LogStartTime 的属性值决定处理逻辑

因为 Java5+ 之后 AspectJ 可以写成 Java 类加注解的方式,*.aj 文件一般都没太大必要了,所以可以和 Spring AOP 共用一个 @Aspect 注解的方面代码 MethodStartAspect

我们将采用编译器织入,因此项目依赖只需要一个 org.aspectj:aspectjrt:1.8.0, 它也不会引入别的组件。同样我们从 Main 方法和测试用例两方面来验证实现的效果,下面是整个测试项目的布局,以及依赖,除掉单元测试的其时就只需要一个 jar 包。 阅读全文 >>

类别: Java/JEE. 标签: , . 阅读(21). 评论(0) »

Spring 下基于自定义注解拦截方法调用

其实很多年前就做过如此的实验,一翻开自己的日志有关于 aspectj site:unmi.cc, 可以找到  2008 年写的日志。真是流光容易把人抛,红了樱桃,绿了巴蕉。只是那时候 Spring 刚步入 2.0, 才翻开强大 AOP 的篇章,还记得彼时只要是直接使用 AspectJ 就要写  *.aj 文件。而如今 Spring 都到 5.0 了,也就是一年前才重拾起 Spring, 这期间 AspectJ 早就可以不用 *.aj 文件,只需普通 Java 文件,加上 @Aspect 和 @Pointcut 之类的注解就行。

本文内容与几年前写过的日志大体相差不大,再缀上一篇纯粹是个人笔记。这里不以 Spring 5.0 为例,仍然是最新的 4.3.11.RELEASE, 并且直接用 Spring, 而非选择  Spring Boot, 因为用了 Spring Boot 常常搞不清楚哪些是自动配置了的。原生的 Spring 可以使自己掌握一个 Spring AOP 的基本要素。

需求:@LogStartTime 注解的方法,在每次进入该方法时把当前时间写入 ThreadLocal 中去,被 @LogStartTime 注解的方法中随时可以获得进入方法的时间 阅读全文 >>

类别: Spring. 标签: . 阅读(21). 评论(0) »

学习并体验 JUnit 5 新特性

上一篇 JUnit 5 快速上手(从 JUnit 4 到 JUnit 5) 介绍了如何在一个项目中同时使用 JUnit 4 和 JUnit 5。现在来开始了解 JUnit 5 的新特性. 我们现在的项目基本是用 Maven 来管理依赖,在 Maven 项目中如何引入 JUnit 5 可以参考官方例子 junit5-maven-consumer. 我们知道 JUnit 5 包括三个模块,不用 JUnit 4 的话只要 Platform 和 Jupiter, 而 Jupiter Maven 模块本身依赖于 JUnit Platform, 因此应用 JUnit 5 的项目 Maven 配置就是

这样在当前的 IntelliJ IDEA(2017.2.4) 可以执行 JUnit 5 的测试用例。但要让 Maven 找到 JUnit 5 的测试用例,还得在 pom.xml 中加上 阅读全文 >>

类别: Java/JEE. 标签: . 阅读(24). 评论(0) »

JUnit 中是以测试方法为一个独立的生命周期

 

在研究 JUnit 5 新特性的时候,学习到其中有一节 Test Instance Lifecycle, 才意识到对 JUnit 的理解一直存在一个误区,以为 JUnit 是以测试类为一个生命周期的,其实不然。不管是 JUnit 5 还是 JUnit 4 或更早的版本,JUnit 都是以测试方法为一个独立的生命周期。

比如在同一个类中多个测试方法使用了同一个实例变量的情况下,总会用一个  @After 方法来复位该实例变量,现在才知道那是多余的。像下面的代码

阅读全文 >>

类别: Java/JEE. 标签: . 阅读(18). 评论(0) »

JUnit 5 快速上手(从 JUnit 4 到 JUnit 5)

一直在关注 JUnit 5 的演进,自两年前首个 ALPHA 版后,经历了 6 的 Milestone, 3 个 RC 终于在 2017/09/10 正式发布了。其实还从未对其深究过,今天算是正式开始体验。

不像以往的版本,JUnit 5 现在是三个模块的合体 JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage

  1. JUnit Platform: 运行测试的基础平台。还定义了开发测试框架的 TestEngine API。并提供了命令行执行测试以及与 Gradle, Maven, JUnit4 Runner 的集成
  2. JUnit Jupiter: 包含了新的编程和扩展模型。它还提供了一个运行新型测试的 TestEngine 实现
  3. JUnit Vintage: 提供了一个让 JUnit Platform 运行 JUnit 3 和 JUnit 4 的 TestEngine 实现

以上三个模块分工还是很明确,因此

  1. 从现有的 JUnit 4 项目步入到 JUnit 5 至少两 JUnit Platform 和  JUnit Vintage 两个
  2. 建立全新项目可以只引入  JUnit Platform 和 JUnit Jupiter
  3. 混合型当然是三个全部引入

但是由于 jar 包之间本身存在某种依赖关系,所以实际上 pom.xml 可以比想像的更简单 阅读全文 >>

类别: Java/JEE. 标签: . 阅读(45). 评论(0) »

理解 Spring 定时任务的 fixedRate 和 fixedDelay 的区别

用过  Spring 的 @EnableScheduling 的都知道,我们用三种形式来部署计划任务,即 @Scheduled 注解的 fixedRate(fixedRateString), fixedDelay(fixedDelayString), 以及 cron. cron 不在这里讨论的范畴。我们着重在如何理解 fixedRate 和 fixedDelay 的区别。

在 Spring 的  Scheduled 注解的 JavaDoc 对此的解释很简单

public abstract long fixedRate
Execute the annotated method with a fixed period in milliseconds between invocations.

public abstract long fixedDelay
Execute the annotated method with a fixed period in milliseconds between the end of the last invocation and the start of the next.

只是说是 fixedRate 任务两次执行时间间隔是任务的开始点,而 fixedDelay 的间隔是前次任务的结束与下次任务的开始。

大致用示意字符串来表示如下(每个 T1, 或 T2 代表任务执行秒数(每次任务执行时间不定),假定 fixedRate 或  fixedDelay 的值是 5 秒,用 W 表示等待的数)

fixedRate:    T1.T1WWWT2.T2.T2WW.T3.T3.T3.T3.T3.T4.T4.T4.T4.T4.T4.T4T5T5WWWT6.T6........

fixedDelay:  T1.T1.WWWWW.T2.T2.T2WWWWW.T3.T3.T3.T3.T3.WWWWW.T4.T4.T4.T4.T4.T4.T4.WWWWWT6.T6......

一般来说能理解到上面两个场景已经差不多了,相比而言 fixedDelay 简单些,盯着上一次任务的屁股就行。 阅读全文 >>

类别: Spring. 标签: , . 阅读(131). 评论(0) »

Java 反射有效的修改 final 属性值

两年前写过一篇 Java 反射修改 final 属性值, 在这里重新温习一下,假设有个类

class Person {
    public final String name = "Mike";
}

这里声明 name 为非静态的属性只是为了说明反射修改 final 属性无关乎静态不静态,静态只是表现在它是一个类属性,在一个类加载器空间只会有一份拷贝,仅此而已。

创建一个通用方法进行反射修改属性值

调用 modify(...) 方法试图修改 person 的 name 属性 阅读全文 >>

类别: Java/JEE. 标签: . 阅读(49). 评论(0) »

自定义类加载器动态加载 JDBC 驱动

我们可以用自定义的 URLClassLoader 从外部动态加载类,并使用它。但数据库驱动的管理类 DriverManager 却不比较苛刻,不承认非当前应用系统加载器加载的驱动类。见 DriverManager 的 JavaDoc 

When the method getConnection is called, the DriverManager will attempt to locate a suitable driver from amongst those loaded at initialization and those loaded explicitly using the same classloader as the current applet or application

对于有有应用自定义类加载器加载数据库驱动类的需求时,就要对原 Driver 简单包装一下。继续往后会说介绍为什么要这么做。

说明一下,DriverManager 能够根据 JDBC 连接字符串匹配到驱动类,所以一般来说都不需要显式调用 DriverManager.registerDriver() 方法。

先看 DriverManager 在应用外部驱动类时会出现什么情况 阅读全文 >>

类别: Database, Java/JEE. 阅读(46). 评论(1) »

函数定义 Kotlin V.S. Scala

关注 Kotlin 已有段时日了,真是因为 Google 把它扶正而跑来跟风。因为进行想在 Java 与 Scala 间找一个折中的编程语言,也就是 Kotlin。这是一篇好几月前列的我 想像中理想编程语言的几个特征,琢磨来去当今也就 Kotlin 比较符合我的口味。很早就想买 《Kotlin IN ACTION》这本书,因那是 Kotlin 1.1 刚出,而出版的书只涵盖到了 Kotlin, 所以未出手。看看再有一本好的那样的书估计也不是一时半会儿,所以今天还是把那本书弄到手了,至于 Kotlin 1.1 后的特性自个去补充。

尽管书中未提及 Kotlin 语言的设计灵感来自于何种语言,  但我的直觉就是与 Scala 太多相似之处,但没有 Scala 简单,并揉合一些 Swift 的特性,因此我在阅读 《Kotlin IN ACTION》时更多的会和 Scala 相比较。

第一个主题是关于 Kotlin 函数的定义与约定。Kotlin 的基本定义格式与 Scala 是类似的

//Kotlin
fun max(a: Int, b: Int): Int {
    return if (a > b) a else b
}

注:Kotlin 也像 Scala 一样,if 不再是一个控制语句,而是一个表达式,所以它是有返回值的。与  Java 有不同的是,Kotlin 的赋值语句是没有返回值的,不能用作 val b = (a = 3), 而 Scala 的赋值语句总是返回 Unit 阅读全文 >>

类别: Kotlin, Scala. 标签: . 阅读(108). 评论(0) »

Spring 定时任务(Schedule) 和线程

Spring 定时任务实例

Spring 中使用定时任务很简单,只需要  @EnableScheudling 注解启用即可,并不要求是一个 Spring Mvc 的项目。对于一个 Spring Boot 项目,使用定时任务的简单方式如下:

pom.xml 中

Application.java 阅读全文 >>

类别: Spring. 标签: , . 阅读(815). 评论(0) »
Page 1 of 4112345...102030...Last »