java动态代理实现Proxy和InvocationHandler cglib

概念:

静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 
动态代理:在程序运行时,运用反射机制动态创建而成。

JDK的动态代理用起来非常简单,当它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包。

JDK动态代理实现

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

public class ProxyTest {
    static StringBuilder sBuilder=new StringBuilder();
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        
        //代理类字节码
Class clazzProxy1=    Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
//代理类构造方法列表,没有无参构造方法
System.out.println("...........begin constructors list............");
    Constructor[] constructors= clazzProxy1.getConstructors();
     for(Constructor constructor:constructors){
         StringBuilder sBuilder=new StringBuilder();
        sBuilder.append(constructor.getName()).append("(");
        Class[] clazzparams =constructor.getParameterTypes();
    
        for(Class clazzparam:clazzparams){
            
            sBuilder.append(clazzparam.getName()).append(",");
            
        }
        
        if(clazzparams.length!=0){
            
            sBuilder.deleteCharAt(sBuilder.length()-1);
        }
        sBuilder.append(")");
        System.out.println( sBuilder.toString());
     }
    
    //代理类方法列表
    System.out.println("...........begin methods list............");
     
    Method[] methods= clazzProxy1.getMethods();
     for(Method method:methods){
         StringBuilder sBuilder=new StringBuilder();
        sBuilder.append(method.getName()).append("(");
        Class[] clazzparams =method.getParameterTypes();
    
        for(Class clazzparam:clazzparams){
            
            sBuilder.append(clazzparam.getName()).append(",");
            
        }
        
        if(clazzparams.length!=0){
            
            sBuilder.deleteCharAt(sBuilder.length()-1);
        }
        sBuilder.append(")");
        System.out.println( sBuilder.toString());
     }
     
     //通过字节码创建代理类的实例,不能用newInstance(),构造方法传入InvocationHandler
     System.out.println("...........begin create instance object............");
    
        Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.class);
        
    Collection proxy1=    (Collection) constructor.newInstance(new InvocationHandler(){

            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                
                return null;
            }
            
        });
        
    System.out.println(proxy1);
    proxy1.clear();//无返回值的方法成功

    //一步到位创建代理类实例
    Collection proxy2=(Collection) Proxy.newProxyInstance(Collection.class.getClassLoader(),new Class[]{Collection.class}, new InvocationHandler(){
        ArrayList target=new ArrayList<>();//被代理对象,目标对象
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            
            long begintime=System.currentTimeMillis();
            Object retVal=method.invoke(target, args);
            long endtime=System.currentTimeMillis();
            System.out.println(method.getName()+" running time is " +(endtime-begintime));
            return retVal;
        }
        
    });
    
    proxy2.add("lhm");
    proxy2.add("zxx");
    proxy2.add("bxd");
    System.out.println(proxy2.size());
    System.out.println(proxy2.getClass().getName());
    }
        
    
    
    
}

CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,

主要是对指定的类生成一个子类覆盖其中的所有方法,所以该类或方法不能声明称final的。

spring中Aspect动态代理设置

Spring提供了两种方式来生成代理对象: JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。

默认的策略是如果目标类是接口,则使用JDK动态代理技术,如果目标对象没有实现接口,则默认会采用CGLIB代理。

如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。

本文出自 “点滴积累” 博客,请务必保留此出处http://tianxingzhe.blog.51cto.com/3390077/1719600

时间: 2024-11-03 23:43:42

java动态代理实现Proxy和InvocationHandler cglib的相关文章

Java 动态代理(Proxy)

动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实,代理对象对客户隐藏了实际对象.动态代理可以对请求进行其他的一些处理,在不允许直接访问某些类,或需要对访问做一些特殊处理等,这时候可以考虑使用代理.目前 Java 开发包中提供了对动态代理的支持,但现在只支持对接口的实现. 主要是通过 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口. Proxy 类主要用来获取动态代理对象,InvocationHand

求救,java动态代理问题!

问题描述 各位同学:如何得到Java动态代理方法Proxy.newProxyInstance产生的临时代理类的内部结构是什么? 解决方案 解决方案二:你看下这个类的原码吧.解决方案三:http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/index.html?ca=drs-cn-0121我当时看动态代理的时候看过这篇文章,写的很好,推荐一下

Java动态代理机制分析及扩展,第1部分

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要 简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所 有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可 以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架.通过阅 读本文,读者将会对 Java 动态代理机制有更加深入的理解.本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内 部实现. 代理:设计模式 代理是一种常用的设

设计模式之动态代理(dynamic proxy)

1 动态代理与静态代理 我们从上一篇设计模式之代理模式一文中已经知道,在代理模式中代理对象和被代理对象一般实现相同的接口,调用者与代理对象进行交互.代理的存在对于调用者来说是透明的,调用者看到的只是接口.这就是传统的代理模式静态代理的特点. 那么传统的静态代理模式有什么问题呢?如果需要代理的类只有一个,那么静态代理没什么问题,如果有很多类需要代理呢,用静态代理的话就需要为每一个类创建一个代理类,显然这么做太过繁琐也容易出错.为此,JDK 5引入的动态代理机制,允许开发人员在运行时刻动态的创建出代

Java 动态代理机制分析及扩展

简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟推演了动态代理类的可能实现,向读者阐述了一个完整的 Java 动态代理运作过程,希望能帮助读者加深对 Java 动态代理的理解和应用. 引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的

详解java动态代理模式_java

本文针对java动态代理进行知识点整理,具体内容如下 一. JAVA的动态代理(比较官方说法) 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处 理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的 对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提 供特定的服务. 按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工

详解Java动态代理的实现机制_java

一.概述 代理是一种设计模式,其目的是为其他对象提供一个代理以控制对某个对象的访问,代理类负责为委托类预处理消息,过滤消息并转发消息以及进行消息被委托类执行后的后续处理.为了保持行为的一致性,代理类和委托类通常会实现相同的接口. 按照代理的创建时期,代理类可分为两种: 静态代理:由程序员创建代理类或特定工具自动生成源代码再对其编译,也就是说在程序运行前代理类的.class文件就已经存在.动态代理:在程序运行时运用反射机制动态创建生成. 下面在将动态代理的实现机制之前先简单介绍一下静态代理. 二.

java动态代理的基础问题

问题描述 java动态代理的基础问题 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.List; import java.util.Vector; public class VectorProxy implements InvocationHandler { private Object pro

关于java动态代理的一个奇怪问题

问题描述 在使用java动态代理时遇到一个怪异的现象,不知道正不正常:由Proxy..newProxyInstance()生成的代理对象会同时代理除了接口以外的其他方法.源码如下:public interface Talkable {public void talk();public void cry();}public class Baby implements Talkable{@Overridepublic void cry() {System.out.println("Wa!!!!!!!