java 自定义注解 (custom annotation)
By:Roy.LiuLast updated:2014-01-12
最近几年写程序,越来越流行注解方式,比如 spring,hibernate 都从原来的xml配置方式转向了注解方式,原因在于写注解很方便,减少了XML 文件的配置,如果全部用XML 配置,一个大型的应用,怎么也得有成百上千的XML文件。那么怎么自定义类似于spring 的注解方式呢。
java 提供了@interface 来自定义注解的申明
在定义了这个注解之后,可以将这个注解 加到方法上面,比如 @Test(enable = false) .
另外定义个类级别的注解:@TesterInfo
写一个单元测试,利用自定义的注解 @Test, @TesterInfo
利用java 反射 读取注解并做相关的处理
运行 RunTest 类的Main 方法,就可以得到结果了。
当然,如果你想更好的处理类似这样的功能,可以采用spring aop + AspectJ 方式 来完成,有空我将继续测试.
java 提供了@interface 来自定义注解的申明
在定义了这个注解之后,可以将这个注解 加到方法上面,比如 @Test(enable = false) .
package com.yihaomen.test.core; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) //只能在方法上应用. public @interface Test { //是否开启 public boolean enabled() default true; }
另外定义个类级别的注解:@TesterInfo
package com.yihaomen.test.core; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) //类级别 public @interface TesterInfo { public enum Priority { LOW, MEDIUM, HIGH } Priority priority() default Priority.MEDIUM; String[] tags() default ""; String createdBy() default "yihaomen"; String lastModified() default "11/01/2014"; }
写一个单元测试,利用自定义的注解 @Test, @TesterInfo
package com.yihaomen.test; import com.mkyong.test.core.Test; import com.mkyong.test.core.TesterInfo; import com.mkyong.test.core.TesterInfo.Priority; @TesterInfo( priority = Priority.HIGH, createdBy = "yihaomen.com", tags = {"sales","test" } ) public class TestExample { @Test void testA() { if (true) throw new RuntimeException("This test always failed"); } @Test(enabled = false) void testB() { if (false) throw new RuntimeException("This test always passed"); } @Test(enabled = true) void testC() { if (10 > 1) { // do nothing, this test always passed. } } }
利用java 反射 读取注解并做相关的处理
package com.yihaomen.test; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import com.mkyong.test.core.Test; import com.mkyong.test.core.TesterInfo; public class RunTest { public static void main(String[] args) throws Exception { System.out.println("Testing..."); int passed = 0, failed = 0, count = 0, ignore = 0; Classobj = TestExample.class; // Process @TesterInfo if (obj.isAnnotationPresent(TesterInfo.class)) { Annotation annotation = obj.getAnnotation(TesterInfo.class); TesterInfo testerInfo = (TesterInfo) annotation; System.out.printf("%nPriority :%s", testerInfo.priority()); System.out.printf("%nCreatedBy :%s", testerInfo.createdBy()); System.out.printf("%nTags :"); int tagLength = testerInfo.tags().length; for (String tag : testerInfo.tags()) { if (tagLength > 1) { System.out.print(tag + ", "); } else { System.out.print(tag); } tagLength--; } System.out.printf("%nLastModified :%s%n%n", testerInfo.lastModified()); } // Process @Test for (Method method : obj.getDeclaredMethods()) { // if method is annotated with @Test if (method.isAnnotationPresent(Test.class)) { Annotation annotation = method.getAnnotation(Test.class); Test test = (Test) annotation; // if enabled = true (default) if (test.enabled()) { try { method.invoke(obj.newInstance()); System.out.printf("%s - Test '%s' - passed %n", ++count, method.getName()); passed++; } catch (Throwable ex) { System.out.printf("%s - Test '%s' - failed: %s %n", ++count, method.getName(), ex.getCause()); failed++; } } else { System.out.printf("%s - Test '%s' - ignored%n", ++count, method.getName()); ignore++; } } } System.out.printf("%nResult : Total : %d, Passed: %d, Failed %d, Ignore %d%n", count, passed, failed, ignore); } }
运行 RunTest 类的Main 方法,就可以得到结果了。
Testing... Priority :HIGH CreatedBy :yihaomen.com Tags :sales, test LastModified :11/01/2014 1 - Test 'testA' - failed: java.lang.RuntimeException: This test always failed 2 - Test 'testC' - passed 3 - Test 'testB' - ignored Result : Total : 3, Passed: 1, Failed 1, Ignore 1
当然,如果你想更好的处理类似这样的功能,可以采用spring aop + AspectJ 方式 来完成,有空我将继续测试.
From:一号门
Previous:java 获取HttpRequest Header 的几种方法
COMMENTS