`
jbosscn
  • 浏览: 149772 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Introduce ARE4j - a common Annotation Resolving Engine for Java

    博客分类:
  • java
阅读更多

ARE4j 是一个用于Java的通用Annotation解析引擎。

1. ARE4j提供了一个通用的引擎来解析Annotation;可以用于解析任何类型的自定义annotation;

2. 之所以设计为引擎,而不是框架或者容器,因为这样,可以尽可能少的减少对现有代码的影响,如果你的项目已经很好的应用的工厂模式,那么只需简单的替换或者重写Factory类即可开始使用ARE4j来解析代码中的Annotation;

3.ARE4j只依赖于javassist,这样不会对现有项目带来任何影响;

4.ARE4j非常简单易用;

 

Scannotation 和 Jandex是另外两个Annotation工具。Scannotation可以在运行时扫描你的Jar和Classpath,并将index存储于内存中;Jandex在编译时刻扫描代码中annotation,并将index存储于文件中。Scannotation和Jandex可以用来发现annotation,并能在运行时提高annotation的索引速度。而ARE4j不同,它是在运行时对Class中的Annotation进行解析,从而实现设计人员对于Annotation所要实现的逻辑。

 

使用ARE4j是非常简单的,只需要认识Engine类以及几个为了实现Resolver类需要了解的几个接口。

Engine 是ARE4j最核心的类,需要通过Engine类来完成对ARE4j的各种调用。Engine类完成一下功能:

1. register/unregister annotation resolver class

2. Check if annotation reasonable

3. Create proxy object by javassist

4. Cache annotations while parsing class first time

 

通过调用 Engine.newProxyInstance(Class<? extends T> clazz) 返回的是一个proxy object, 在执行的时候,proxy object会按照要求对 Class/Constructor/Field/Method/Parameter上的Annotation进行解析。

 

为了实现Annotation的解析逻辑,需要实现各种AnnotationResolver接口,一共有5个接口:

ClassAnnotationResolver, ConstructorAnnotationResolver, FieldAnnotationResolver, MethodAnnotationResolver, ParameterAnnotationResolver。以 MethodAnnotationResolver 为例,为了完整的解析可用于 Method 的 Annotation,需要实现以下的方法:

 

 

这3个方法分别会在对象构造之后,方法执行之前以及方法执行之后会被调用,可以实现相关的代码实现Annotation所要期望的逻辑。

 

接下来看一个简单的Example来看看如何定义Annotation、实现Resolver以及使用Engine,完整的例子可以参考 ARE4j testcase.

 

1. 定义Annotation

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestMethodAnnotation {

}
 

 

 

2. 实现  Resolver

 

public class TestMethodResolver implements MethodAnnotationResolver {

    public void resolveMethodAnnotationAfterConstruct(MethodResolveContext methodResolveContext) throws ResolverException {
    }

    public void resolveMethodAnnotationBeforeMethod(MethodResolveContext methodResolveContext) throws ResolverException {
        methodResolveContext.setParameters(new String[]{"value2_changed"});
    }

    public void resolveMethodAnnotationAfterMethod(MethodResolveContext methodResolveContext) throws ResolverException {
    }
}
 

 

 

3. 假设一个TestObject需要使用 Annotation

public class TestObject {
    private Object field2 = "value1";

    @TestMethodAnnotation
    public void setField2_2(Object field2) {
        this.field2 = field2;
    }
    public Object getField2() {
        return field2;
    }
}
 

 

 

4. TestCase

@Test
    public void testMethodAnnotation() throws Exception{
        Engine.registerAnnotation(TestMethodAnnotation.class, new TestMethodResolver());
        TestObject testObject = Engine.newProxyInstance(TestObject.class);
        testObject.setField2_2("");
        // TestMethodResolver will check the init value and set value to "value2_change"
        Assert.assertEquals("value2_changed", testObject.getField2());
    }
 

 

 

这就是例子的全部,实现Resolver以及调用 Engine 都十分简单。

 

 

ARE4j能用在什么地方?

1. 可以使用在任何需要自定义和解析 Annotation 的地方;

2. 可以作为基础的类库用在Annotation驱动的 tool/framework/container。 比如:像Junit4一样的使用annotation的测试框架;像ejb3  jpa这样的容器;以及用来做Permance测试的工具。

 

 

参考:

https://github.com/yongyang/are4j
http://scannotation.sourceforge.net
https://github.com/jbossas/jandex

 

附件是ARE4j的讲解PPT,欢迎查看。

 

 

分享到:
评论
1 楼 左右互搏 2012-11-07  
好东西。抽时间看看

相关推荐

Global site tag (gtag.js) - Google Analytics