java 代理知多少

代理实现形式有哪些?
什么是静态代理和动态代理?

   静态代理就是一种形式上的称呼,其实就是对原实现做了又一次封装,实现和”代理“之间是一对一的关系,专职保姆(编译期)
动态代理分为2种,
    一种jdk官方的,只能对接口做代理,还要提供接口的实现,生成快,執行慢
    一种是cglib,普通类非final可继承,scm字节码技术  生成類慢,執行快

    一种是基于AspectJ ,修改目标类字节,织入新内容,编译时动态的织入,不生成新的class

    一种基于instrumentation(修改目标类的字节码、类装载的时候动态拦截去修改,基于javaagent) -javaagent:spring-instrument-4.3.8.RELEASE.jar (类装载的时候 插入动态代理的字节码,不会生成全新的Class )

2个角色:

   代理类:加什么功能,就由它在原实现上增强

   委托类:原实现

 

jdk官方的实现是:

这里jvm在runnable期间,创建了代理对象并通过它,对原接口实现做了功能增强。我们要做的,就是在创建代理对象时,告诉jvm要对谁增强,增强做什么。这里要做的事情都放在了invoke方法里,因为我们知道,在代理方法之前会先进入invoke

        //参数一:loader:获取实现类的加载器
        //参数二:interfaces:获取实现类所实现的接口数组 
        //参数三:代理要做的事情 注意:这里接收了一个外面的参数,crud的实现类!
 CURD user =(CURD) Proxy.newProxyInstance(curdImpl.getClass().getClassLoader(), new Class[]{CURD.class}, new InvocationHandler() {
            @Override
            
            /**
             * 有了代理对象,下面要做点什么
             * proxy:代理对象本身 类似于this
             * method:当前具体执行的方法 反射
             * args:调用方法传递的实际参数数组 可变参数的底层也是数组(若执行的方法内有参数 则需有args)
             */
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("11");
                Object invoke = method.invoke(curdImpl);//反射实现
                //将目标类的返回对象紧接着再返回给调用者
                return invoke;
            }
			
        });

上面的方法Proxy.newProxyInstance(classLoader,interfaces,invocaterHandler),其实是下面几个方法的封装,简化了形式

// InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发  
// 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用  
InvocationHandler handler = new InvocationHandlerImpl(..);   

// 通过 Proxy 为包括 Interface 接口在内的一组接口动态创建代理类的类对象  
Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... });   

// 通过反射从生成的类对象获得构造函数对象  
Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class });   

// 通过构造函数对象创建动态代理类实例  
Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler });  

 

在JDK动态代理中涉及如下角色:

业务接口Interface、业务实现类target、业务处理类Handler、JVM在内存中生成的动态代理类$Proxy0

动态代理的过程:

第一:Proxy通过传递给它的参数(interfaces/invocationHandler)生成代理类$Proxy0;

第二:Proxy通过传递给它的参数(ClassLoader)来加载生成的代理类$Proxy0的字节码文件;

 

cglib的实现:

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibMethodInterceptor implements MethodInterceptor {   
    
    public Object CglibProxyGeneratory(Class target) {     
        // 创建加强器,用来创建动态代理类
        Enhancer enhancer = new Enhancer();   
        enhancer.setSuperclass(target);        
        enhancer.setCallback(this);    
        return enhancer.create();   
    }   

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("before");
        Object result = proxy.invokeSuper(obj, args);        //Object result = method.invoke(target, args);
        System.out.println("after");
        return result;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值