本文共 4824 字,大约阅读时间需要 16 分钟。
有时候它们的处理没有关联性,有些时候,它们的处理又是有关联性的。
我们用伪代码来示意一下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | if (includeAnnotation(testClass,Abc. class )){ doSomething... } if (includeAnnotation(testClass,Abc. class )){ for (Field field:testClass.getFields){ if (includeAnnotation(testField,AbcField. class )){ dosomething... } } for (Method method:testClass.getMethods){ if (includeAnnotation(testMethod,AbcMethod. class )){ dosomething... } } } |
有的时候,我们可能在类名的处理上还有一些规则,比如:....Service,.....Action,.....View等等,我们的某些注解只可以加在某种类名规则之下,这个时候,判定就又会增加。我们的程序员就不停的在写这些重复,但是却不可缺少的内容。有没有办法让开发人员只写doSomething的内容就好呢??
只要问题可以提得出来,办法总是有的:
可以定义下面的三个类,开发人员只要编写process函数体中的内容就好了。
1 2 3 4 5 6 7 8 9 | public interface AnnotationClassAction { <T> void process(Class<T> clazz, Annotation annotation); } public interface AnnotationMethodAction { <T> void process(Class<T> clazz, Method method, Annotation annotation); } public interface AnnotationPropertyAction{ <T> void process(Class<T> clazz, Field field, Annotation annotation); } |
这对于开发人员来说当然是再熟悉不过的了。
但是总要让上面的逻辑有所体现才是,否则不是就执行错位置了??
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 | < annotation-class-matchers > < annotation-class-matcher class-name = ".*\.annotation\.Annotation.*" annotation-type = ".*Test" > < processor-beans > < processor-bean enable = "true" name = "classAction" > </ processor-bean > </ processor-beans > < annotation-method-matchers > < annotation-method-matcher method-name = "method.*" annotation-type = ".*Test" > < processor-beans > < processor-bean enable = "true" name = "methodAction" > </ processor-bean > </ processor-beans > </ annotation-method-matcher > </ annotation-method-matchers > < annotation-property-matchers > < annotation-property-matcher property-name = "field.*" annotation-type = ".*Test" > < processor-beans > < processor-bean enable = "true" name = "propertyAction" > </ processor-bean > </ processor-beans > </ annotation-property-matcher > </ annotation-property-matchers > </ annotation-class-matcher > </ annotation-class-matchers > |
上面的演示了一个 示例,看起来比较复杂,其实是因为配置的内容为了充分说明,所以看起来有点复杂,实际应用情况不一定要全配的。我给翻译一下:
1 2 3 4 5 | 首先进行注解类的匹配,匹配的类名是*.annotation.Annotation.*,上面加的注解名是*Test,如果匹配呢,就执行classAction处理器。 如果类名匹配,则再进行方法匹配,方法名必须是method*格式的,上面加的注解是*Test类型的注解,匹配成功呢就执行methodAction处理器。 如果类名匹配,再进行属性匹配,属性名必须为field*格式,上面的注解格式是*Test类型,如果匹配呢就执行propertyAction处理器。 |
这样是不是简单了,把所有的匹配工作都通过配置的方式进行实现,开发人员只需要做逻辑处理的部分。
比如下面这样子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class AnnotationClassActionDemo implements AnnotationClassAction { public <T> void process(Class<T> clazz, Annotation annotation) { System.out.println( "className:" + clazz.getName() + " annotation类型:" + annotation.annotationType().getName()); } } public class AnnotationMethodActionDemo implements AnnotationMethodAction { public <T> void process(Class<T> clazz, Method method, Annotation annotation) { System.out.println( "className:" +clazz.getName()+ " annotation类型:" +annotation.annotationType().getName()+ " method名称:" +method.getName()); } } public class AnnotationPropertyActionDemo implements AnnotationPropertyAction { public <T> void process(Class<T> clazz, Field field, Annotation annotation) { System.out.println( "className:" + clazz.getName() + " annotation类型:" + annotation.annotationType().getName() + " field名称:" + field.getName()); } } |
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 | @Test (id= 0 ,description= "class" ) @XStreamAlias ( "sd" ) public class AnnotationDemo1 { @Test (id= 1 ,description= "field1" ) private String field1; @Test (id= 2 ,description= "field2" ) private String field2; @Test (id= 3 ,description= "method1" ) public void method1(){ System.out.println( "method1" ); } @Test (id= 4 ,description= "method2" ) public void method2(){ System.out.println( "method2" ); } public String getField1() { return field1; } public void setField1(String field1) { this .field1 = field1; } public String getField2() { return field2; } public void setField2(String field2) { this .field2 = field2; } } |
进行处理,可以看到正确的处理结果。
1 2 3 4 5 | className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test field名称:field1 className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test field名称:field2 className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test method名称:method1 className:org.tinygroup.annotation.AnnotationDemo1 annotation类型:org.tinygroup.annotation.Test method名称:method2 |
通过上面的的重构,我们可以看到,把开发人员从重复的劳动中解脱出来,而且由于其只处理逻辑部分的内容即可,也避免了一些不必要的逻辑错误引入。
当然,采用配置还是编码的方式配置匹配规则,这个是公说公有理,婆说婆有理,其实两者都支持不就可以了??
总之,通过上面的重构,对编程人员开发注解方面有更大的便捷。
通过文件处理及注解处理的重构,我们看到代码编写及实现确实是优雅了,
解决了代码重复、圈复杂度大、扩展方面的问题,但是性能方面的问题其实是还没有解决的。
转载地址:http://ayrzx.baihongyu.com/