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方法,无法进行代理。

你可能感兴趣的:(anno_proxy)