??xml version="1.0" encoding="utf-8" standalone="yes"?>欧美一区电影,欧美在线二区,自拍偷拍亚洲综合http://www.aygfsteel.com/masen/category/54669.htmlzh-cnTue, 03 Feb 2015 00:32:54 GMTTue, 03 Feb 2015 00:32:54 GMT60Java 创徏对象方式http://www.aygfsteel.com/masen/articles/422168.htmlMasenMasenSat, 10 Jan 2015 14:42:00 GMThttp://www.aygfsteel.com/masen/articles/422168.htmlhttp://www.aygfsteel.com/masen/comments/422168.htmlhttp://www.aygfsteel.com/masen/articles/422168.html#Feedback0http://www.aygfsteel.com/masen/comments/commentRss/422168.htmlhttp://www.aygfsteel.com/masen/services/trackbacks/422168.htmlJava 创徏对象方式Q?br />
    ●  用new语句创徏对象
    ●  q用反射手段,调用java.lang.Class 或?java.lang.reflect.Constructor cȝnewInstance()实例Ҏ
    ●  调用对象的clone()Ҏ
    ●  q用序列化手D?调用java.io.ObjectInputStream 对象?readObject()Ҏ.

分别创徏100万个javaBean Q性能如下Q?br />

//new : 46,47,47,62,47
//clone : 171,188,172,,157,172
//getClass().newInstance() : 140,141,141,,157,172
//Class.forName and newInstance : 1765,1781,1813,1797,1781
//Proxy.newProxyInstance : 2984
//Serializable : 60422

另外试了Field ?Method 执行效率Q?br />
//method : 1406
//feild : 1360 getField("")得到实例和父cȝ“公共”属?span style="white-space:pre">
//getDeclaredField() 得到实例的指定属?Public,protected,dfault,pivate),不包括父cd?/div>
//getFields()q回field数组Q?得到实例 ?父类 的所? “公共”属?br />
动态代理:
JDKQjdk1.7.0_02 
CGLIBQ和spring2.0.6 使用同样的cglib-nodep-2.1_3.jar 
CPUQP8400 2.53GHz 2.53GHz 
试l果4Q?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
CGLIB创徏代理对象速度大概比JDK Proxy?倍,执行速度是JDK Proxy?倍以?/span>

区别Q?br />如果一个目标对象如果实C接口Spring则会选择JDK动态代理策略动态的创徏一个接口实现类Q动态代理类Q来代理目标对象Q可以通俗的理解这个动态代理类是目标对象的另外一个版本,所以这两者之间在强制转换的时候会抛出java.lang.ClassCastException。而所以在默认情况下,如果目标对象没有实现M接口QSpring会选择CGLIB代理Q?其生成的动态代理对象是目标cȝ子类?/span>
spring 配置实用cglib动态代?br /> proxy-target-class 属性设为true ?nbsp;<aop:aspectj-autoproxy proxy-target-class="true"/>


Masen 2015-01-10 22:42 发表评论
]]>
java 注解 (转infoq.com)http://www.aygfsteel.com/masen/articles/422089.htmlMasenMasenTue, 06 Jan 2015 09:54:00 GMThttp://www.aygfsteel.com/masen/articles/422089.htmlhttp://www.aygfsteel.com/masen/comments/422089.htmlhttp://www.aygfsteel.com/masen/articles/422089.html#Feedback0http://www.aygfsteel.com/masen/comments/commentRss/422089.htmlhttp://www.aygfsteel.com/masen/services/trackbacks/422089.html在开发JavaE序Q尤其是Java EE应用的时候,L免不了与各种配置文g打交道。以Java EE中典型的S(pring)S(truts)H(ibernate)架构来说Q?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">Spring?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">Struts?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">Hibernateq三个框枉有自qXML格式的配|文件。这些配|文仉要与Java源代码保存同步,否则的话可能出现错误。而且q些错误有可能到了运行时L被发现。把同一份信息保存在两个地方QL个坏的主意。理想的情况是在一个地方维护这些信息就好了。其它部分所需的信息则通过自动的方式来生成。JDK 5中引入了源代码中的注解(annotationQ这一机制。注解得Java源代码中不但可以包含功能性的实现代码Q还可以d元数据。注解的功能cM于代码中的注释,所不同的是注解不是提供代码功能的说明,而是实现E序功能的重要组成部分。Java注解已经在很多框架中得到了广泛的使用Q用来简化程序中的配|?/p>

使用注解

在一般的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;">@SupressWarningsq两个注解了。用@Override的时候只需要一个简单的声明卛_。这U称为标记注解(marker annotation Q,它的出现׃表了某种配置语义。而其它的注解是可以有自己的配|参数的。配|参C名值对的方式出现。?@SupressWarnings的时候需要类似@SupressWarnings({"uncheck", "unused"})q样的语法。在括号里面的是该注解可供配|的倹{由于这个注解只有一个配|参敎ͼ该参数的名称默认为valueQƈ且可以省略。而花括号则表C是数组cd。在JPA中的@Table注解使用cM@Table(name = "Customer", schema = "APP")q样的语法。从q里可以看到名值对的用法。在使用注解时候的配置参数的值必L~译时刻的常量?/p>

从某U角度来_可以把注解看成是一个XML元素Q该元素可以有不同的预定义的属性。而属性的值是可以在声明该元素的时候自行指定的。在代码中用注解,q当于把一部分元数据从XML文gUd了代码本w之中,在一个地方管理和l护?/p>

开发注?/h2>

在一般的开发中Q只需要通过阅读相关的API文档来了解每个注解的配置参数的含义,q在代码中正用即可。在有些情况下,可能会需要开发自q注解。这在库的开发中比较常见。注解的定义有点cM接口。下面的代码l出了一个简单的描述代码分工安排的注解。通过该注解可以在源代码中记录每个cL接口的分工和q度情况?br />

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Assignment {
    String assignee();
    int effort();
    double finished() default 0;
} 

@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配|参数。方法的名称是参数的名Uͼq回值类型就是参数的cd。可以通过default来声明参数的默认倹{在q里可以看到@Retention?a style="text-decoration: none; color: #286ab2; margin: 0px; border: 0px; padding: 0px; outline: none !important;">@Targetq样的元注解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;">SOURCEq三U,分别表示注解保存在类文g、JVMq行时刻和源代码中。只有当声明为RUNTIME的时候,才能够在q行时刻通过反射API来获取到注解的信息。@Target用来声明注解可以被添加在哪些cd的元素上Q如cd、方法和域等?/p>

在程序中d的注解,可以在编译时L是运行时Lq行处理。在~译时刻处理的时候,是分成多来q行的。如果在某趟处理中生了新的Java源文Ӟ那么需要另外一处理来处理新生成的源文件。如此往复,直到没有新文件被生成为止。在完成处理之后Q再对Java代码q行~译。JDK 5中提供了apt工具用来Ҏ解进行处理。apt是一个命令行工具Q与之配套的q有一套用来描q程序语义结构的Mirror API。Mirror APIQcom.sun.mirror.*Q描q的是程序在~译时刻的静态结构。通过Mirror API可以获取到被注解的Javacd元素的信息,从而提供相应的处理逻辑。具体的处理工作交给apt工具来完成。编写注解处理器的核心是AnnotationProcessorFactory?a style="text-decoration: none; color: #286ab2; outline: none !important; margin: 0px; border: 0px; padding: 0px;">AnnotationProcessor两个接口。后者表C的是注解处理器Q而前者则是ؓ某些注解cd创徏注解处理器的工厂?/p>

以上面的注解AssignmentZQ当每个开发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是根据注解的cd来返回特定的注解处理器;supportedAnnotationTypes是返回该工厂生成的注解处理器所能支持的注解cdQsupportedOptions用来表示所支持的附加选项。在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Ҏ中完成。通过一个声明(DeclarationQ的getAnnotationMirrorsҎ可以获取到该声明上所d的注解的实际倹{得到这些g后,处理h׃难了?/p>

在创建好注解处理器之后,可以通过apt命o行工hҎ代码中的注解q行处理?命o的运行格式是apt -classpath bin -factory annotation.apt.AssignmentApf src/annotation/work/*.javaQ即通过-factory来指定注解处理器工厂cȝ名称。实际上Qapt工具在完成处理之后,会自动调用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.processingq个新的API。对Mirror API也进行了更新QŞ成了新的javax.lang.model包。注解处理器的用也q行了简化,不需要再单独q行aptq样的命令行工具QJava~译器本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.javaq样的方式即可?/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接口提供了获取类、方法和域上的注解的实用Ҏ。比如获取到一个Classcd象之后,通过getAnnotationҎ可以获取到该类上添加的指定注解cd的注解?/p>

实例分析

下面通过一个具体的实例来分析说明在实践中如何来使用和处理注解。假定有一个公司的雇员信息pȝQ从讉K控制的角度出发,寚w员的工资的更新只能由h特定角色的用h能完成。考虑到访问控刉求的普遍性,可以定义一个注解来让开发h员方便的在代码中声明讉K控制权限?br />
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiredRoles
{ String[] value(); } 

下一步则是如何对注解q行处理Q这里用的Java的反APIq结?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>

Masen 2015-01-06 17:54 发表评论
]]>
վ֩ģ壺 | | ²| | Ϲ| ײ| | «Ϫ| | | Ͽ| | Ȫ| ɽ| | ˾| | | ƽ| ƶ| | ɳ| | ʦ| | | | | ղ| ʼ| | | | Ͽ| | | Զ| | ƽ| ɽ| |