anno_proxy

自定义注解

定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

开发步骤

  1. 创建一个@interface

  2. String value();抽象方法用以接收数据

  3. 使用元注解,描述自定义注解

  4. @Target指定注解可以加在哪里
    ElementType.TYPE:可在类和接口上面
    ElementType.METHOD:可方法上
    ElementType.FIELD:可在属性

  5. @Retention指定注解在什么时候有用
    RetentionPolicy.RUNTIME:注解保留到运行时
    RetentionPolicy.ClASS:注解保留到Class文件中
    RetentionPolicy.SOURCE:注解保留到java编译时期

  6. @Inherited可以被继承

jdk动态代理

  1. 被代理类必须实现一个接口,任意接口
public class Bus implements Runnable{}
  1. 创建一个类实现InvocationHandler,该类用来对象代理对象进行方法的增强
public class TimeInvocation implements InvocationHandler{
    private Object target;//被代理对象
    public TimeInvocation(Object target){
        this.target=target;
    }
}
  1. 在invoke()方法中调用被代理对象的方法,并且添加增强的代码
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    long time1=System.currentTimeMillis();
        //调用被代理对象的方法
    method.invoke(target, args);
    long time2=System.currentTimeMillis();
    System.out.println(time2-time1);
    return null;
}
  1. 通过Proxy.newProxyInstance(ClasLoader, Class, InvovationHandler)创建代理类对象

  2. 调用代理对象的方法

TimeInvocation time=new TimeInvocation(s);
Class<?> clazz=s.getClass();
Runnable s1= (Runnable)Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), time);
s1.run();

cglib

public class SayHello {  
    public void say(){  
        System.out.println("hello everyone");  
    }  
} 
public class CglibProxy implements MethodInterceptor{  
    private Enhancer enhancer = new Enhancer();  
    public Object getProxy(Class clazz){  
    //设置需要创建子类的类  
        enhancer.setSuperclass(clazz);  
        enhancer.setCallback(this);  
    //通过字节码技术动态创建子类实例  
        return enhancer.create();  
    }  
    //实现MethodInterceptor接口方法  
    public Object intercept(Object obj, Method method, Object[] args,  
        MethodProxy proxy) throws Throwable {  
        System.out.println("前置代理");  
        //通过代理类调用父类中的方法  
        Object result = proxy.invokeSuper(obj, args);  
        System.out.println("后置代理");  
        return result;  
    }  
}  
public class DoCGLib {  
    public static void main(String[] args) {  
        CglibProxy proxy = new CglibProxy();  
        //通过生成子类的方式创建代理类  
        SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class);  
        proxyImp.say();  
    }  
}  

注意: jdk动态代理与cglib的区别

jdk通实现接口的方式实现动态代理 cglib通过继承的方式实现动态代理

jdk动态代理与cglib如何选择? CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • [TOC] 自定义注解 开发步骤 1.创建一个@interface2.String value();抽象方法用以接...
    呦後阅读 165评论 0 0
  • 什么是注解(Annotation):Annotation(注解)就是Java提供了一种元程序中的元素关联任何信息和...
    九尾喵的薛定谔阅读 3,234评论 0 2
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,378评论 11 349
  • 今晚月色好美 在淡淡的月光里 从前的样子 今晚月色好美 在洗衣池边 溅落的水花 今晚月色好美 在我们彼此回眸的那一...
    味儿铭阅读 229评论 0 4
  • 1.书中自有黄金屋 关于收纳 星星之火 万马奔腾 草原2.天空之城 白云和黑土 我想静静 项链 记事本 3.童话 ...
    杜观音阅读 164评论 0 0