java中动态代理实现机制

v前言:

  代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 

vJAVA各种动态代理实现的比较

v接口

interface AddInterface{
    int add(int a, int b);
}

interface SubInterface{
    int sub(int a, int b);
}

v实现类

class Arithmetic implements AddInterface, SubInterface{
    @Override
    public int sub(int a, int b) {
        return a-b;
    }

    @Override
    public int add(int a, int b) {
        return a+b;
    }
}

v方式1: JDK自带的动态代理

v实现方式

  Java在JDK1.3后引入的动态代理机制,使我们可以在运行期动态的创建代理类。使用动态代理实现AOP需要有四个角色:被代理的类,被代理类的接口,织入器,和InvocationHandler,而织入器使用接口反射机制生成一个代理类,然后在这个代理类中织入代码。被代理的类是AOP里所说的目标,InvocationHandler是切面,它包含了Advice和Pointcut。 

vInvocationHandler接口的实现

class JdkDPQueryHandler implements InvocationHandler{
    private Arithmetic real;
    public JdkDPQueryHandler(Arithmetic real){
        this.real = real;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        System.out.println(method);
        System.out.println("the method: " + methodName + "开始, 参数: "+Arrays.asList(args));
        Object result = method.invoke(real, args);
        System.out.println("the method: "+methodName+"结束, 结果: " + result);
        return result;
    }
}

v创建代理类并且调用代理类

public class Main{
    private static int a = 4, b = 2;

    public static Object createJDKProxy(Arithmetic real){
        Object proxyArithmetic = Proxy.newProxyInstance(real.getClass().getClassLoader(),
                real.getClass().getInterfaces(), new JdkDPQueryHandler(real));
        return proxyArithmetic;
    }

    public static void main(String[] args){
        Arithmetic real = new Arithmetic();
        Object proxyArithmetic = createJDKProxy(real);
        ((AddInterface)proxyArithmetic).add(a, b);
        ((SubInterface)proxyArithmetic).sub(a, b);
    }
}

v方式2:动态字节码生成(cglib)

v实现方式

  Enhancer和MethodInterceptor。Enhancer可以用来动态的生成一个类,这个类可以继承指定的一个类,实现指定的一些接口。同时,Enhancer在生成一个类之前需要指定一个Callback,当类方法调用时,方法的执行被分配给这个Callback,MethodInterceptor是一个使用比较多的继承自Callback的接口,它只有一个方法声明。

v接口InvocationHandler(jdk中)和接口MethodInterceptor(cglib中)对比

public interface MethodInterceptor extends Callback  {
    public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,MethodProxy proxy) throws Throwable;
}  
public interface InvocationHandler {
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}  

    从参数构成上,methodInterceptor的输入参数比Invocationhandler多1个,其实前3个参数对象的含义与Invocationhandler的含义是相同的。

  第一个参数表示调用方法来自哪个对象;

  第二个参数表示调用方法的Method对象;

  第三个参数表示此次调用的输入参数列表;

  多出来的参数是MethodProxy 类型的,它应该是cglib生成用来代替Method对象的一个对象,使用MethodProxy比调用JDK自身的Method直接执行方法效率会有提升。

v实现1

  MethodInterceptor接口的实现

class CglibDPQueryInterceptor implements MethodInterceptor{
    private Arithmetic real;
    public CglibDPQueryInterceptor(Arithmetic real){
        this.real = real;
    }

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        String methodName = method.getName();
        System.out.println(method);
        System.out.println("the method: " + methodName + "开始, 参数: "+Arrays.asList(args));
        //Object result = method.invoke(real, args);//两种方式都是可以得
        Object result = proxy.invoke(real, args);
        System.out.println("the method: "+methodName+"结束, 结果: " + result);
        return result;
    }
}

  创建代理类并调用代理类

public class Main{
    private static int a = 4, b = 2;
   public static Object createCglibProxy(Arithmetic real){
         Enhancer enhancer = new Enhancer();
         enhancer.setCallback(new CglibDPQueryInterceptor(real));
         enhancer.setInterfaces(real.getClass().getInterfaces());
         return enhancer.create();
    }

    public static void main(String[] args){
        Arithmetic real = new Arithmetic();
        Object proxyArithmetic = createCglibProxy(real);
        ((AddInterface)proxyArithmetic).add(a, b);
        ((SubInterface)proxyArithmetic).sub(a, b);
    }
}

   注意了,MethodProxy在对执行函数的时候,提供了2个方法

public Object invoke (Object obj, Object[] args) throws Throwable
public Object invokeSuper(Object obj, Object[] args) throws Throwable

  其中,javadoc上说这个invoke()方法可以用于相同类中的其他对象的方法执行,也就是说这个方法中的obj需要传入相同一个类的另一个对象(上述方法中就是传入了Arithmetic类的不同对象),否则会进入无限递归循环(测试之后还真是出现了StackOverflowError)。仔细的想一想就会发现,public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy)中的target是实现的代理类对象,通过target调用add()方法时会触发intercept()方法被调用,如果在intercept()方法中再调用method.invoke(target, args),就相当于add()方法中又调用add()方法,导致无限的递归循环。但是如果执行method.invoke(real, args)则不会,因为real和target是同一个类不同对象,real是真实逻辑主题,target是真实主题real的代理。

  下面一个例子来模拟一下:

interface SolveInterface{
    void solve();
}

class Real implements SolveInterface{
    public void solve(){
        System.out.println("Real Solve!");
    }
}

class Target extends Real{
    private Object obj;

    public void setObject(Object obj){
        this.obj = obj;
    }

    private void invoke(){
        try {
            Method method = SolveInterface.class.getMethod("solve", new Class[]{});
            method.invoke(obj, new Class[]{});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void solve(){
        System.out.println("Target Solve!");
        invoke();
    }
}

  

public class Main{public static void main(String[] args) throws Exception{
        Target target = new Target();
        target.setObject(new Real());//正确
//target.setObject(target);//发生循环调用
        target.solve();
    }
}

  其实Method的invoke()方法会根据obj的类型去调用对应的solve()方法,也就是多态性。

v实现2

  MethodInterceptor接口的实现

class CglibDPQueryInterceptor implements MethodInterceptor{

    @Override
    public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        String methodName = method.getName();
        System.out.println(method);
        System.out.println("the method: " + methodName + "开始, 参数: "+Arrays.asList(args));
        //  打印类信息 :target.getClass();省略
        Object result = proxy.invokeSuper(target, args);
        System.out.println("the method: "+methodName+"结束, 结果: " + result);
        return result;
    }
}

  创建代理类并调用代理类

public class Main{
    private static int a = 4, b = 2;
public static Object createCglibProxy(){
         Enhancer enhancer = new Enhancer();
         enhancer.setCallback(new CglibDPQueryInterceptor());
         enhancer.setSuperclass(Arithmetic.class);
         return enhancer.create();
    }

    public static void main(String[] args){
        Arithmetic real = new Arithmetic();

        Object proxyArithmetic = createCglibProxy();

        ((AddInterface)proxyArithmetic).add(a, b);
        ((SubInterface)proxyArithmetic).sub(a, b);
    }
}

  注意了,实现2中Enhancer 没有设置接口,因为设置了Superclass了(也就是代理类的父类是Arithmetic),我们的代理类会继承它,而Arithmetic已经实现了我们的接口。为了证明这一点,可以在MethodInterceptor的 intercept方法中打印 target.getClass()的类信息,你会发现cglib的两种方式代理类的父类是不同的。如下:

  (如果需要打印类信息代码,请参考:http://www.cnblogs.com/hujunzheng/p/5132943.html

  实现1:

public class com.test.Arithmetic$$EnhancerByCGLIB$$4fa786eb extends java.lang.Object

  实现2:

public class com.test.Arithmetic$$EnhancerByCGLIB$$4fa786eb extends com.test.Arithmetic

v方式3:javassist生成动态代理(代理工厂创建 或者 动态代码创建)  

  Javassist是一个编辑字节码的框架,可以让你很简单地操作字节码。它可以在运行期定义或修改Class。使用Javassist实现AOP的原理是在字节码加载前直接修改需要切入的方法。这比使用Cglib实现AOP更加高效,并且没太多限制,实现原理如下图: 

v实现1:

接口的实现

class JavassistDPQueryHandler implements MethodHandler{

    @Override
    public Object invoke(Object target, Method method, Method proxy, Object[] args) throws Throwable {
        String methodName = method.getName();
        System.out.println(method);
        System.out.println("the method: " + methodName + "开始, 参数: "+Arrays.asList(args));
        Object result = proxy.invoke(target, args);
        System.out.println("the method: "+methodName+"结束, 结果: " + result);
        return result;
    }
}

创建代理类并调用代理类

public class Main{
    private static int a = 4, b = 2;
public static Object createJavassistProxy() throws Exception{
        ProxyFactory factory = new ProxyFactory();
        factory.setSuperclass(Arithmetic.class);
        factory.setHandler(new JavassistDPQueryHandler());
        return factory.createClass().newInstance();
    }

    public static void main(String[] args) throws Exception{
        Arithmetic real = new Arithmetic();

        Object proxyArithmetic = createJavassistProxy();

        ((AddInterface)proxyArithmetic).add(a, b);
        ((SubInterface)proxyArithmetic).sub(a, b);
    }
}

  注意:MethodHandler接口中invoke方法的定义,如下:

public Object invoke(Object target, Method method, Method proxy, Object[] args)

  method代表调用方法的Method对象,proxy是代理类产生并代替method的对象,否则用method.invoke(target, args)会产生无限循环调用。

v实现2:

  (来自:http://cuishen.iteye.com/blog/421464),代码注释很详细,仔细研究一下就会懂了!

  javassist使用动态java代码常见代理过程和前文的方法略有不同。javassist内部可以通过动态java代码,生成字节码。这种方式创建的动态代理可以非常灵活,甚至可以在运行时产生业务逻辑。

//自定义拦截器接口
interface InterceptorHandler {  

    /**
     * 调用动态代理对象的方法将反射本方法,可在本方法实现中添加类似AOP的事前事后操作,只有在本方法体中加入如下代码
     * 被代理的方法才会被执行,返回值将返回给代理最后返回给程序
     * @param obj Object 被代理的对象
     * @param method Method 被代理对象的方法
     * @param args Object[] 被代理对象的方法的参数
     * @return Object 被代理对象的方法执行后的返回值
     * @throws Throwable
     */
    public Object invoke(Object obj, Method method, Object[] args) throws Throwable;
}

//拦截器的实现
class InterceptorHandlerImpl implements InterceptorHandler{
    @Override
    public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        System.out.println(method);
        System.out.println("the method: " + methodName + "开始, 参数: "+Arrays.asList(args));
        Object result = method.invoke(obj, args);
        System.out.println("the method: "+methodName+"结束, 结果: " + result);
        return result;
    }
}

class MyProxyImpl {
    /** 动态代理类的类名后缀 */
    private final static String PROXY_CLASS_NAME_SUFFIX = "$MyProxy_";
    /** 拦截器接口 */
    private final static String INTERCEPTOR_HANDLER_INTERFACE = "com.test.InterceptorHandler";
    /** 动态代理类的类名索引,防止类名重复 */
    private static int proxyClassIndex = 1;  

    /**
     * 暴露给用户的动态代理接口,返回某个接口的动态代理对象,注意本代理实现需和com.cuishen.myAop.InterceptorHandler拦截器配合
     * 使用,即用户要使用本动态代理,需先实现com.cuishen.myAop.InterceptorHandler拦截器接口
     * @param interfaceClassName String 要动态代理的接口类名, e.g test.StudentInfoService
     * @param classToProxy String 要动态代理的接口的实现类的类名, e.g test.StudentInfoServiceImpl
     * @param interceptorHandlerImplClassName String 用户提供的拦截器接口的实现类的类名
     * @return Object 返回某个接口的动态代理对象
     * @throws InstantiationException
     * @throws IllegalAccessException
     * @throws NotFoundException
     * @throws CannotCompileException
     * @throws ClassNotFoundException
     * @see com.cuishen.myAop.InterceptorHandler
     */
    public static Object newProxyInstance(String interfaceClassName, String classToProxy, String interceptorHandlerImplClassName) throws InstantiationException, IllegalAccessException, NotFoundException, CannotCompileException, ClassNotFoundException {
        Class interfaceClass = Class.forName(interfaceClassName);
        Class interceptorHandlerImplClass = Class.forName(interceptorHandlerImplClassName);
        return dynamicImplementsInterface(classToProxy, interfaceClass, interceptorHandlerImplClass);
    }  

    /**
     * 动态实现要代理的接口
     * @param classToProxy String 要动态代理的接口的实现类的类名, e.g test.StudentInfoServiceImpl
     * @param interfaceClass Class 要动态代理的接口类, e.g test.StudentInfoService
     * @param interceptorHandlerImplClass Class 用户提供的拦截器接口的实现类
     * @return Object 返回某个接口的动态代理对象
     * @throws NotFoundException
     * @throws CannotCompileException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private static Object dynamicImplementsInterface(String classToProxy, Class interfaceClass, Class interceptorHandlerImplClass) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException {
        ClassPool cp = ClassPool.getDefault();
        String interfaceName = interfaceClass.getName();
        //动态指定代理类的类名
        String proxyClassName = interfaceName + PROXY_CLASS_NAME_SUFFIX + proxyClassIndex++;
        //要实现的接口的包名+接口名
        String interfaceNamePath = interfaceName;  

        CtClass ctInterface = cp.getCtClass(interfaceNamePath);
        CtClass cc = cp.makeClass(proxyClassName);
        cc.addInterface(ctInterface);
        Method [] methods = interfaceClass.getMethods();
        for(int i = 0; i < methods.length; i++) {
            Method method = methods[i];
            dynamicImplementsMethodsFromInterface(classToProxy, cc, method, interceptorHandlerImplClass, i);
        }
        return (Object)cc.toClass().newInstance();
    }  

    /**
     * 动态实现接口里的方法
     * @param classToProxy String 要动态代理的接口的实现类的类名, e.g test.StudentInfoServiceImpl
     * @param implementer CtClass 动态代理类的包装
     * @param methodToImpl Method 动态代理类里面要实现的接口方法的包装
     * @param interceptorClass Class 用户提供的拦截器实现类
     * @param methodIndex int 要实现的方法的索引
     * @throws CannotCompileException
     */
    private static void dynamicImplementsMethodsFromInterface(String classToProxy, CtClass implementer, Method methodToImpl, Class interceptorClass, int methodIndex) throws CannotCompileException {
        String methodCode = generateMethodCode(classToProxy, methodToImpl, interceptorClass, methodIndex);
        CtMethod cm = CtNewMethod.make(methodCode, implementer);
        implementer.addMethod(cm);
    }  

    /**
     * 动态组装方法体,当然代理里面的方法实现并不是简单的方法拷贝,而是反射调用了拦截器里的invoke方法,并将接收到的参数进行传递
     * @param classToProxy String 要动态代理的接口的实现类的类名, e.g test.StudentInfoServiceImpl
     * @param methodToImpl Method 动态代理类里面要实现的接口方法的包装
     * @param interceptorClass Class 用户提供的拦截器实现类
     * @param methodIndex int 要实现的方法的索引
     * @return String 动态组装的方法的字符串
     */
    private static String generateMethodCode(String classToProxy, Method methodToImpl, Class interceptorClass, int methodIndex) {
        String methodName = methodToImpl.getName();
        String methodReturnType = methodToImpl.getReturnType().getName();
        Class[] parameters = methodToImpl.getParameterTypes();
        Class[] exceptionTypes = methodToImpl.getExceptionTypes();
        StringBuffer exceptionBuffer = new StringBuffer();
        //组装方法的Exception声明
        if(exceptionTypes.length > 0) exceptionBuffer.append(" throws ");
        for(int i = 0; i < exceptionTypes.length; i++) {
            if(i != exceptionTypes.length - 1) exceptionBuffer.append(exceptionTypes[i].getName()).append(",");
            else exceptionBuffer.append(exceptionTypes[i].getName());
        }
        StringBuffer parameterBuffer = new StringBuffer();
        //组装方法的参数列表
        for(int i = 0; i < parameters.length; i++) {
            Class parameter = parameters[i];
            String parameterType = parameter.getName();
            //动态指定方法参数的变量名
            String refName = "a" + i;
            if(i != parameters.length - 1) parameterBuffer.append(parameterType).append(" " + refName).append(",");
            else parameterBuffer.append(parameterType).append(" " + refName);
        }
        StringBuffer methodDeclare = new StringBuffer();
        //方法声明,由于是实现接口的方法,所以是public
        methodDeclare.append("public ").append(methodReturnType).append(" ").append(methodName).append("(").append(parameterBuffer).append(")").append(exceptionBuffer).append(" {\n");
        String interceptorImplName = interceptorClass.getName();
        //方法体
        methodDeclare.append(INTERCEPTOR_HANDLER_INTERFACE).append(" interceptor = new ").append(interceptorImplName).append("();\n");
        //反射调用用户的拦截器接口
        methodDeclare.append("Object returnObj = interceptor.invoke(Class.forName(\"" + classToProxy + "\").newInstance(), Class.forName(\"" + classToProxy + "\").getMethods()[" + methodIndex + "], ");
        //传递方法里的参数
        if(parameters.length > 0) methodDeclare.append("new Object[]{");
        for(int i = 0; i < parameters.length; i++) {
            //($w) converts from a primitive type to the corresponding wrapper type: e.g.
            //Integer i = ($w)5;
            if(i != parameters.length - 1) methodDeclare.append("($w)a" + i + ",");
            else methodDeclare.append("($w)a" + i);
        }
        if(parameters.length > 0) methodDeclare.append("});\n");
        else methodDeclare.append("null);\n");
        //对调用拦截器的返回值进行包装
        if(methodToImpl.getReturnType().isPrimitive()) {
            if(methodToImpl.getReturnType().equals(Boolean.TYPE)) methodDeclare.append("return ((Boolean)returnObj).booleanValue();\n");
            else if(methodToImpl.getReturnType().equals(Integer.TYPE)) methodDeclare.append("return ((Integer)returnObj).intValue();\n");
            else if(methodToImpl.getReturnType().equals(Long.TYPE)) methodDeclare.append("return ((Long)returnObj).longValue();\n");
            else if(methodToImpl.getReturnType().equals(Float.TYPE)) methodDeclare.append("return ((Float)returnObj).floatValue();\n");
            else if(methodToImpl.getReturnType().equals(Double.TYPE)) methodDeclare.append("return ((Double)returnObj).doubleValue();\n");
            else if(methodToImpl.getReturnType().equals(Character.TYPE)) methodDeclare.append("return ((Character)returnObj).charValue();\n");
            else if(methodToImpl.getReturnType().equals(Byte.TYPE)) methodDeclare.append("return ((Byte)returnObj).byteValue();\n");
            else if(methodToImpl.getReturnType().equals(Short.TYPE)) methodDeclare.append("return ((Short)returnObj).shortValue();\n");
        } else {
            methodDeclare.append("return (" + methodReturnType + ")returnObj;\n");
        }
        methodDeclare.append("}");
        System.out.println(methodDeclare.toString());
        return methodDeclare.toString();
    }  

}  

public class Main{
    public static void main(String[] args) throws Exception{    
//分别对应 代理类要实现的接口类名, 需要代理类的类名, 用户自定义拦截器实现类的类名
        Object proxyArithmetic = MyProxyImpl.newProxyInstance("com.test.ArithmeticInterface", "com.test.Arithmetic", 
"com.test.InterceptorHandlerImpl");
        ((ArithmeticInterface)proxyArithmetic).add(a, b);
        ((ArithmeticInterface)proxyArithmetic).sub(a, b);
    }
}

  打印一下动态实现接口的代码如下:

public int add(int a0,int a1) {
com.test.InterceptorHandler interceptor = new com.test.InterceptorHandlerImpl();
Object returnObj = interceptor.invoke(Class.forName("com.test.Arithmetic").newInstance(), Class.forName("com.test.Arithmetic").getMethods()[0], new Object[]{($w)a0,($w)a1});
return ((Integer)returnObj).intValue();
}
public int sub(int a0,int a1) {
com.test.InterceptorHandler interceptor = new com.test.InterceptorHandlerImpl();
Object returnObj = interceptor.invoke(Class.forName("com.test.Arithmetic").newInstance(), Class.forName("com.test.Arithmetic").getMethods()[1], new Object[]{($w)a0,($w)a1});
return ((Integer)returnObj).intValue();
}

 

时间: 2025-01-31 07:44:25

java中动态代理实现机制的相关文章

详解java中动态代理实现机制_java

代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. JAVA各种动态代理实现的比较 接口 interface AddInterface{ int add(int a, int b); } interface SubInterfa

java实现动态代理方法浅析_java

一些Java项目中在mybatis与spring整合中有MapperScannerConfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类. 有鉴于此,本文浅析了java的动态代理. 本文使用动态代理模拟处理事务的拦截器. 接口: public interface UserService { public void addUser(); public void removeUser(); public void searchUser(); } 实现类: public class

java动态代理-如何理解Java的动态代理?

问题描述 如何理解Java的动态代理? Java的动态代理怎么理解? 哪位高手能详细解释一下这个问题,最好举个例子吧. 解决方案 彻底理解JAVA动态代理http://www.cnblogs.com/flyoung2008/archive/2013/08/11/3251148.html 解决方案二: Java动态代理详解

基于java中stack与heap的区别,java中的垃圾回收机制的相关介绍_java

#. 在java中有两类内存.分别称为stack(堆栈)和heap(堆). stack是程序内存空间,因此所有的基本类型和对象的引用是存在stack中. heap是java虚拟机储存对象的,它是一个巨大的内存,当你创造一个对象,java虚拟机把对象放入heap中,把创造的对象的地址放入stack中. 因此,基本类型.对象的引用储存在stack中:对象储存在heap中. #. java中的垃圾回收机制 当你new一个新的对象,java分配必需的内存.当你用完一个对象时,java的垃圾回收器为你把内

Java中的类反射机制

一.反射的概念 :反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力.这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩.其中LEAD/LEAD++ .OpenC++ .MetaXa和OpenJava等就是基于反射机制的语言.最近,反射机制也被应用到了视窗系统.操作系统和文件系统中. 反射本身并不是一个新概念,它可能会使我们联想到光学中的反射概念,尽管计算机科学

在Java中动态执行类的静态方法

在Java中,通过Class.forName()方法可以动态决定加载哪一个类,这个功能对于相同接口的不同实现来讲非常有用.比如对于设计好的数据库连接池接口,我们可以有多种的接口实现类来完成相同的功能,同时用户可以简单的通过修改配置文件来指定实际使用哪一个实现类,在源代码里面通过读取配置文件信息,并用Class.forName(configClassName).getInstance()就可以构造一个特定的实现类实例,而不用每次修改源代码.这样对于程序来讲只用关心接口的定义,用户只用进行配置文件的

Java 8 动态代理的新技巧:为什么使用动态代理?

动态代理(Dynamic proxies)是 Java 1.3 引入的特性,在 J2EE 的远程调用中应用非常广泛.给定一个抽象接口以及这个接口的具体实现,就可以通过创建两个额外的类来实现这个接口的远程调用了(如,跨JVM).首先,在 源JVM上实现相应的接口,并将调用细节序列化后通过网络传输.然后,在目标JVM上,获取到序列化后的调用的细节,并分配给具体的的类去调用. 没有动态代理和反射,开发者不得不为每个远程接口提供两个类.一个动态代理是运行时产生的类,实现一个或多个接口,接口中每个方法的调

Java实现动态代理_java

Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类: (1)InvocationHandler:该接口中仅定义了一个方法         public object invoke(Object obj,Method method, Object[] args)         在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组. 这个抽象方法在代理类中动态实现. (2)Proxy:

java使用动态代理来实现AOP(日志记录)的实例代码_java

下面是一个AOP实现的简单例子: 首先定义一些业务方法: 复制代码 代码如下: /** * Created with IntelliJ IDEA. * Author: wangjie  email:tiantian.china.2@gmail.com * Date: 13-9-23 * Time: 下午3:49 */public interface BussinessService {    public String login(String username, String password