JDKåQšjdk1.7.0_02CGLIB创å¾ä»£ç†å¯¹è±¡é€Ÿåº¦å¤§æ¦‚比JDK Proxyæ…?å€ï¼Œæ‰§è¡Œé€Ÿåº¦æ˜¯JDK Proxyçš?å€ä»¥ä¸?/span>
CGLIBåQšå’Œspring2.0.6 ä½¿ç”¨åŒæ ·çš„cglib-nodep-2.1_3.jar
CPUåQšP8400 2.53GHz 2.53GHz
‹¹‹è¯•¾l“æžœ4åQ?nbsp;Create JDK Proxy: 43 ms
Create CGLIB Proxy: 129 ms
Run JDK Proxy: 940 ms, 1,500,069 t/s
Run CGLIB Proxy: 299 ms, 4,715,937 t/s
在一般的Javaå¼€å‘ä¸åQŒæœ€å¸¸æŽ¥è§¦åˆ°çš„å¯èƒ½å°±æ˜?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">@Overrideå’?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">@SupressWarnings˜q™ä¸¤ä¸ªæ³¨è§£äº†ã€‚ä‹É用@Override的时候åªéœ€è¦ä¸€ä¸ªç®€å•的声明å›_¯ã€‚è¿™¿Uç§°ä¸ºæ ‡è®°æ³¨è§£ï¼ˆmarker annotation åQ‰ï¼Œå®ƒçš„出现ž®×ƒ»£è¡¨äº†æŸç§é…ç½®è¯ä¹‰ã€‚而其它的注解是å¯ä»¥æœ‰è‡ªå·±çš„é…¾|®å‚数的。酾|®å‚æ•îC»¥å值对的方å¼å‡ºçŽ°ã€‚ä‹Éç”?@SupressWarnings的时候需è¦ç±»ä¼¼@SupressWarnings({"uncheck", "unused"})˜q™æ ·çš„è¯æ³•。在括å·é‡Œé¢çš„æ˜¯è¯¥æ³¨è§£å¯ä¾›é…¾|®çš„倹{€‚ç”±äºŽè¿™ä¸ªæ³¨è§£åªæœ‰ä¸€ä¸ªé…¾|®å‚敎ͼŒè¯¥å‚æ•°çš„å称默认为valueåQŒåƈ且å¯ä»¥çœç•¥ã€‚而花括å·åˆ™è¡¨½Cºæ˜¯æ•°ç»„¾cÕdž‹ã€‚在JPAä¸çš„@Table注解使用¾cÖM¼¼@Table(name = "Customer", schema = "APP")˜q™æ ·çš„è¯æ³•。从˜q™é‡Œå¯ä»¥çœ‹åˆ°å值对的用法。在使用注解时候的é…ç½®å‚æ•°çš„值必™åÀL˜¯¾~–译时刻的常é‡ã€?/p>
从柿U角度æ¥è¯ß_¼Œå¯ä»¥æŠŠæ³¨è§£çœ‹æˆæ˜¯ä¸€ä¸ªXMLå…ƒç´ åQŒè¯¥å…ƒç´ å¯ä»¥æœ‰ä¸åŒçš„预定义的属性。而属性的值是å¯ä»¥åœ¨å£°æ˜Žè¯¥å…ƒç´ 的时候自行指定的。在代ç ä¸ä‹É用注解,ž®Þq›¸å½“于把一部分元数æ®ä»ŽXMLæ–‡äšg¿UÕdˆ°äº†ä»£ç 本íw«ä¹‹ä¸ï¼Œåœ¨ä¸€ä¸ªåœ°æ–¹ç®¡ç†å’Œ¾l´æŠ¤ã€?/p>
在一般的开å‘ä¸åQŒåªéœ€è¦é€šè¿‡é˜…读相关的API文档æ¥äº†è§£æ¯ä¸ªæ³¨è§£çš„é…ç½®å‚æ•°çš„å«ä¹‰ï¼Œòq¶åœ¨ä»£ç 䏿£¼‹®ä‹É用å³å¯ã€‚在有些情况下,å¯èƒ½ä¼šéœ€è¦å¼€å‘自å·Þqš„æ³¨è§£ã€‚这在库的开å‘䏿¯”较常è§ã€‚注解的定义有点¾cÖM¼¼æŽ¥å£ã€‚下é¢çš„ä»£ç ¾l™å‡ºäº†ä¸€ä¸ªç®€å•çš„æè¿°ä»£ç 分工安排的注解。通过该注解å¯ä»¥åœ¨æºä»£ç ä¸è®°å½•æ¯ä¸ª¾cÀLˆ–接å£çš„分工和˜q›åº¦æƒ…况ã€?br />
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Assignment { String assignee(); int effort(); double finished() default 0; }
@interface用æ¥å£°æ˜Žä¸€ä¸ªæ³¨è§£ï¼Œå…¶ä¸çš„æ¯ä¸€ä¸ªæ–¹æ³•å®žé™…ä¸Šæ˜¯å£°æ˜Žäº†ä¸€ä¸ªé…¾|®å‚数。方法的åç§°ž®±æ˜¯å‚æ•°çš„å¿UŽÍ¼Œ˜q”å›žå€¼ç±»åž‹å°±æ˜¯å‚æ•°çš„¾cÕdž‹ã€‚å¯ä»¥é€šè¿‡defaultæ¥å£°æ˜Žå‚数的默认倹{€‚在˜q™é‡Œå¯ä»¥çœ‹åˆ°@Retentionå’?a style="text-decoration: none; color: #286ab2; margin: 0px; border: 0px; padding: 0px; outline: none !important;">@Target˜q™æ ·çš„元注解åQŒç”¨æ¥å£°æ˜Žæ³¨è§£æœ¬íw«çš„è¡ŒäØ“ã€‚@Retention用æ¥å£°æ˜Žæ³¨è§£çš„ä¿ç•™ç–略,æœ?a style="text-decoration: none; color: #286ab2; margin: 0px; border: 0px; padding: 0px; outline: none !important;">CLASSã€?a style="text-decoration: none; color: #286ab2; margin: 0px; border: 0px; padding: 0px; outline: none !important;">RUNTIMEå’?a style="text-decoration: none; color: #286ab2; margin: 0px; border: 0px; padding: 0px; outline: none !important;">SOURCE˜q™ä¸‰¿U,分别表示注解ä¿å˜åœ¨ç±»æ–‡äšgã€JVM˜q行时刻和æºä»£ç ä¸ã€‚åªæœ‰å½“声明为RUNTIME的时候,æ‰èƒ½å¤Ÿåœ¨˜q行时刻通过åå°„APIæ¥èŽ·å–到注解的信æ¯ã€‚@Target用æ¥å£°æ˜Žæ³¨è§£å¯ä»¥è¢«æ·»åŠ åœ¨å“ªäº›¾cÕdž‹çš„å…ƒç´ ä¸ŠåQŒå¦‚¾cÕdž‹ã€æ–¹æ³•和域ç‰ã€?/p>
在程åºä¸æ·ÕdŠ çš„æ³¨è§£ï¼Œå¯ä»¥åœ¨ç¼–译时åˆÀLˆ–是è¿è¡Œæ—¶åˆÀL¥˜q›è¡Œå¤„ç†ã€‚在¾~–译时刻处ç†çš„æ—¶å€™ï¼Œæ˜¯åˆ†æˆå¤š‘Ÿæ¥˜q›è¡Œçš„。如果在æŸè¶Ÿå¤„ç†ä¸äñ”生了新的Javaæºæ–‡ä»Óž¼Œé‚£ä¹ˆž®±éœ€è¦å¦å¤–一‘Ÿå¤„ç†æ¥å¤„ç†æ–°ç”Ÿæˆçš„æºæ–‡ä»¶ã€‚å¦‚æ¤å¾€å¤ï¼Œç›´åˆ°æ²¡æœ‰æ–°æ–‡ä»¶è¢«ç”Ÿæˆä¸ºæ¢ã€‚在完æˆå¤„ç†ä¹‹åŽåQŒå†å¯¹Javaä»£ç ˜q›è¡Œ¾~–译。JDK 5ä¸æä¾›äº†apt工具用æ¥å¯Ò޳¨è§£è¿›è¡Œå¤„ç†ã€‚apt是一个命令行工具åQŒä¸Žä¹‹é…套的˜q˜æœ‰ä¸€å¥—ç”¨æ¥æ˜q°ç¨‹åºè¯ä¹‰ç»“构的Mirror API。Mirror APIåQˆcom.sun.mirror.*åQ‰æ˜q°çš„æ˜¯ç¨‹åºåœ¨¾~–è¯‘æ—¶åˆ»çš„é™æ€ç»“构。通过Mirror APIå¯ä»¥èŽ·å–到被注解的Java¾cÕdž‹å…ƒç´ 的信æ¯ï¼Œä»Žè€Œæä¾›ç›¸åº”的处ç†é€»è¾‘。具体的处ç†å·¥ä½œäº¤ç»™apt工具æ¥å®Œæˆã€‚编写注解处ç†å™¨çš„æ ¸å¿ƒæ˜¯AnnotationProcessorFactoryå’?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">AnnotationProcessor两个接å£ã€‚åŽè€…表½Cºçš„æ˜¯æ³¨è§£å¤„ç†å™¨åQŒè€Œå‰è€…åˆ™æ˜¯äØ“æŸäº›æ³¨è§£¾cÕdž‹åˆ›å¾æ³¨è§£å¤„ç†å™¨çš„工厂ã€?/p>
以上é¢çš„æ³¨è§£Assignmentä¸ÞZ¾‹åQŒå½“æ¯ä¸ªå¼€å‘äh员都在æºä»£ç 䏿›´æ–°è¿›åº¦çš„è¯ï¼Œž®±å¯ä»¥é€šè¿‡ä¸€ä¸ªæ³¨è§£å¤„ç†å™¨æ¥ç”Ÿæˆä¸€ä¸ªé¡¹ç›®æ•´ä½“进度的报告ã€?首先是注解处ç†å™¨å·¥åŽ‚çš„å®žçŽ°ã€?br />
public class AssignmentApf implements AnnotationProcessorFactory { public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> atds,? AnnotationProcessorEnvironment env) { if (atds.isEmpty()) { return AnnotationProcessors.NO_OP; } return new AssignmentAp(env); //˜q”回注解处ç†å™? } public Collection<String> supportedAnnotationTypes() { return Collections.unmodifiableList(Arrays.asList("annotation.Assignment")); } public Collection<String> supportedOptions() { return Collections.emptySet(); } }
AnnotationProcessorFactoryæŽ¥å£æœ‰ä¸‰ä¸ªæ–¹æ³•:getProcessorForæ˜¯æ ¹æ®æ³¨è§£çš„¾cÕdž‹æ¥è¿”回特定的注解处ç†å™¨ï¼›supportedAnnotationTypes是返回该工厂生æˆçš„æ³¨è§£å¤„ç†å™¨æ‰€èƒ½æ”¯æŒçš„æ³¨è§£¾cÕdž‹åQ›supportedOptions用æ¥è¡¨ç¤ºæ‰€æ”¯æŒçš„é™„åŠ é€‰é¡¹ã€‚åœ¨˜q行apt命ä×o行工å…ïLš„æ—¶å€™ï¼Œå¯ä»¥é€šè¿‡-Aæ¥ä¼ 递é¢å¤–çš„å‚æ•°¾l™æ³¨è§£å¤„ç†å™¨åQŒå¦‚-Averbose=true。当工厂通过 supportedOptionsæ–ÒŽ³•å£°æ˜Žäº†æ‰€èƒ½è¯†åˆ«çš„é™„åŠ é€‰é¡¹ä¹‹åŽåQŒæ³¨è§£å¤„ç†å™¨ž®±å¯ä»¥åœ¨˜q行时刻通过AnnotationProcessorEnvironmentçš„getOptionsæ–ÒŽ³•获å–到选项的实际倹{€‚注解处ç†å™¨æœ¬èín的基本实现如下所½Cºã€?br />
public class AssignmentAp implements AnnotationProcessor { private AnnotationProcessorEnvironment env; private AnnotationTypeDeclaration assignmentDeclaration; public AssignmentAp(AnnotationProcessorEnvironment env) { this.env = env; assignmentDeclaration = (AnnotationTypeDeclaration) env.getTypeDeclaration("annotation.Assignment"); } public void process() { Collection<Declaration> declarations = env.getDeclarationsAnnotatedWith(assignmentDeclaration); for (Declaration declaration : declarations) { processAssignmentAnnotations(declaration); } } private void processAssignmentAnnotations(Declaration declaration) { Collection<AnnotationMirror> annotations = declaration.getAnnotationMirrors(); for (AnnotationMirror mirror : annotations) { if (mirror.getAnnotationType().getDeclaration().equals(assignmentDeclaration)) { Map<AnnotationTypeElementDeclaration, AnnotationValue> values = mirror.getElementValues(); String assignee = (String) getAnnotationValue(values, "assignee"); //èŽ·å–æ³¨è§£çš„å€? } } } }
注解处ç†å™¨çš„处ç†é€»è¾‘都在processæ–ÒŽ³•ä¸å®Œæˆã€‚通过一个声明(DeclarationåQ‰çš„getAnnotationMirrorsæ–ÒŽ³•ž®±å¯ä»¥èŽ·å–到该声明上所æ·ÕdŠ çš„æ³¨è§£çš„å®žé™…å€¹{€‚得到这些å€ég¹‹åŽï¼Œå¤„ç†èµäh¥ž®×ƒ¸éš¾äº†ã€?/p>
在创建好注解处ç†å™¨ä¹‹åŽï¼Œž®±å¯ä»¥é€šè¿‡apt命ä×o行工å…äh¥å¯ÒŽºä»£ç ä¸çš„æ³¨è§£˜q›è¡Œå¤„ç†ã€?命ä×oçš„è¿è¡Œæ ¼å¼æ˜¯apt -classpath bin -factory annotation.apt.AssignmentApf src/annotation/work/*.javaåQŒå³é€šè¿‡-factoryæ¥æŒ‡å®šæ³¨è§£å¤„ç†å™¨å·¥åŽ‚¾cÈš„å称。实际上åQŒapt工具在完æˆå¤„ç†ä¹‹åŽï¼Œä¼šè‡ªåŠ¨è°ƒç”¨javacæ¥ç¼–译处ç†å®ŒæˆåŽçš„æºä»£ç ã€?/p>
JDK 5ä¸çš„apt工具的丑³ä¹‹å¤„在于它是Oracleæä¾›çš„ç§æœ‰å®žçŽ°ã€‚åœ¨JDK 6ä¸ï¼Œé€šè¿‡JSR 269把自定义注解处ç†å™¨è¿™ä¸€åŠŸèƒ½˜q›è¡Œäº†è§„范化åQŒæœ‰äº†æ–°çš?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">javax.annotation.processing˜q™ä¸ªæ–°çš„API。对Mirror API也进行了更新åQŒåÅžæˆäº†æ–°çš„javax.lang.model包。注解处ç†å™¨çš„ä‹É用也˜q›è¡Œäº†ç®€åŒ–,ä¸éœ€è¦å†å•独˜q行apt˜q™æ ·çš„命令行工具åQŒJava¾~–译器本íw«å°±å¯ä»¥å®Œæˆå¯Ò޳¨è§£çš„处ç†ã€‚å¯¹äºŽåŒæ ïLš„功能åQŒå¦‚果用JSR 269çš„åšæ³•,åªéœ€è¦ä¸€ä¸ªç±»ž®±å¯ä»¥äº†ã€?br />
@SupportedSourceVersion(SourceVersion.RELEASE_6) @SupportedAnnotationTypes("annotation.Assignment") public class AssignmentProcess extends AbstractProcessor { private TypeElement assignmentElement; public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); Elements elementUtils = processingEnv.getElementUtils(); assignmentElement = elementUtils.getTypeElement("annotation.Assignment"); } public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(assignmentElement); for (Element element : elements) { processAssignment(element); } } private void processAssignment(Element element) { List<? extends AnnotationMirror> annotations = element.getAnnotationMirrors(); for (AnnotationMirror mirror : annotations) { if (mirror.getAnnotationType().asElement().equals(assignmentElement)) { Map<? extends ExecutableElement, ? extends AnnotationValue> values = mirror.getElementValues(); String assignee = (String) getAnnotationValue(values, "assignee"); //èŽ·å–æ³¨è§£çš„å€? } } } }
仔细比较上é¢ä¸¤æ®µä»£ç åQŒå¯ä»¥å‘现它们的基本¾l“构是类似的。ä¸åŒä¹‹å¤„在于JDK 6ä¸é€šè¿‡å…ƒæ³¨è§?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">@SupportedAnnotationTypesæ¥å£°æ˜Žæ‰€æ”¯æŒçš„æ³¨è§£ç±»åž‹ã€‚å¦å¤–æ˜q°ç¨‹åºé™æ€ç»“构的javax.lang.model包ä‹É用了ä¸åŒçš„类型å¿U°ã€‚ä‹Éç”¨çš„æ—¶å€™ä¹Ÿæ›´åŠ ½Ž€å•,åªéœ€è¦é€šè¿‡javac -processor annotation.pap.AssignmentProcess Demo1.java˜q™æ ·çš„æ–¹å¼å³å¯ã€?/p>
上é¢ä»‹ç»çš„这两ç§åšæ³•éƒ½æ˜¯åœ¨ç¼–è¯‘æ—¶åˆ»è¿›è¡Œå¤„ç†çš„。而有些时候则需è¦åœ¨˜q行时刻æ¥å®Œæˆå¯¹æ³¨è§£çš„处ç†ã€‚这个时候就需è¦ç”¨åˆ°Java的垮„API。垮„APIæä¾›äº†åœ¨˜q行时刻è¯Õd–注解信æ¯çš„æ”¯æŒã€‚丘q‡å‰ææ˜¯æ³¨è§£çš„ä¿ç•™ç–略声明的是è¿è¡Œæ—¶ã€‚Javaåå°„APIçš?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">AnnotatedElementæŽ¥å£æä¾›äº†èŽ·å–ç±»ã€æ–¹æ³•和域上的注解的实用æ–ÒŽ³•。比如获å–到一个Class¾cÕd¯¹è±¡ä¹‹åŽï¼Œé€šè¿‡getAnnotationæ–ÒŽ³•ž®±å¯ä»¥èŽ·å–åˆ°è¯¥ç±»ä¸Šæ·»åŠ çš„æŒ‡å®šæ³¨è§£¾cÕdž‹çš„æ³¨è§£ã€?/p>
下é¢é€šè¿‡ä¸€ä¸ªå…·ä½“的实例æ¥åˆ†æžè¯´æ˜Žåœ¨å®žè·µä¸å¦‚何æ¥ä½¿ç”¨å’Œå¤„ç†æ³¨è§£ã€‚å‡å®šæœ‰ä¸€ä¸ªå…¬å¸çš„雇员信毾pÈ»ŸåQŒä»Žè®‰K—®æŽ§åˆ¶çš„角度出å‘,寚w›‡å‘˜çš„工资的更新åªèƒ½ç”±å…ähœ‰ç‰¹å®šè§’色的用æˆäh‰èƒ½å®Œæˆã€‚考虑到访问控刉™œ€æ±‚çš„æ™®éæ€§ï¼Œå¯ä»¥å®šä¹‰ä¸€ä¸ªæ³¨è§£æ¥è®©å¼€å‘äh员方便的在代ç ä¸å£°æ˜Žè®‰K—®æŽ§åˆ¶æƒé™ã€?br />
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiredRoles
{ String[] value(); }
下一æ¥åˆ™æ˜¯å¦‚何对注解˜q›è¡Œå¤„ç†åQŒè¿™é‡Œä‹É用的Java的垮„APIòq¶ç»“å?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">动æ€ä»£ç?/a>ã€‚ä¸‹é¢æ˜¯åЍæ€ä»£ç†ä¸çš„InvocationHandler接å£çš„实现ã€?br />
public class AccessInvocationHandler<T> implements InvocationHandler { final T accessObj; public AccessInvocationHandler(T accessObj) { this.accessObj = accessObj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { RequiredRoles annotation = method.getAnnotation(RequiredRoles.class); //通过åå°„APIèŽ·å–æ³¨è§£ if (annotation != null) { String[] roles = annotation.value(); String role = AccessControl.getCurrentRole(); if (!Arrays.asList(roles).contains(role)) { throw new AccessControlException("The user is not allowed to invoke this method."); } } return method.invoke(accessObj, args); } }
在具体ä‹É用的时候,首先è¦é€šè¿‡Proxy.newProxyInstanceæ–ÒŽ³•创å¾ä¸€ä¸ªEmployeeGateway的接å£çš„代熾c»ï¼Œä½¿ç”¨è¯¥ä»£ç†ç±»æ¥å®Œæˆå®žé™…çš„æ“作ã€?/p>