java 动态代理(模式) InvocationHandler(为类中方法执行前或后添加内容)

java 动态代理(模式) InvocationHandler(为类中方法执行前或后添加内容)

动态代理属于Java反射的一种。

当我们得到一个对象,想动态的为其一些方法每次被调用前后追加一些操作时,我们将会用到java动态代理。

·
package com.liuyx;

public interface Itf {
    public abstract void printMe();

    public abstract void printSth(String me);
}
·

接着是它的实现:

复制代码
package com.liuyx;

public class Cls implements Itf {

    @Override
    public void printMe() {
        System.out.println("I'm Cls!");
    }

    @Override
    public void printSth(String str) {
        System.out.println(str);
    }

}
复制代码

 

我们的目的就是通过动态代理技术,在Cls这个类的对象的两个方法执行前后,加上一些打印操作。

 

现在我们实现一个InvocationHandler,把我们想要通过代理者被代理者追加的操作都写在invoke方法里面:

复制代码
package com.liuyx;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class StandardInvocation implements InvocationHandler {

    private Object obj;

    StandardInvocation(Object obj){
        this.obj=obj;
    }

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

}
复制代码

首先、这里面有一个obj,这个obj是必须的,我们既然要做代理,我们必须知道我们是给谁做代理,这里的obj就是被代理者。

动态代理说到底也是代理,代理模式里就要求有一个被代理者。

然后是invoke的三个参数、第一个参数就是代理者,如果你想对代理者做一些操作可以使用这个参数;第二个就是被执行的方法,第三个是执行该方法所需的参数。

当你执行代理者的某个方法的时候,最后跑的都是invoke方法。

 

然后是用法:

复制代码
    public static void main(String[] args) {
        //创建一个被代理者
        Cls c = new Cls();
        //创建一个InvocationHandler,描述我们希望代理者执行哪些操作
        InvocationHandler i = new StandardInvocation(c);
        //通过刚才创建的InvocationHandler,创建真正的代理者。第一个参数是类加载器,第二个参数是这个代理者实现哪些接口
        Itf pxy = (Itf) Proxy.newProxyInstance(Cls.class.getClassLoader(), new Class[] { Itf.class }, i);
        pxy.printSth("Hi");
    }
复制代码

pxy就是c的代理者。

 

最后来一个稍微改进的写法:

复制代码
package com.liuyx;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class InvocationHandlerTest implements InvocationHandler {

    private Object target;

    Object bind(Object i) {
        target = i;
        Object warpedItf;
        warpedItf = Proxy.newProxyInstance(target.getClass().getClassLoader(), i.getClass().getInterfaces(), this);
        return warpedItf;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before method excute!");
        method.invoke(target, args);
        System.out.println("after method excute!");
        return null;
    }

    public static void main(String[] args) {
        Cls c = new Cls();
        InvocationHandlerTest pxy = new InvocationHandlerTest();
        Itf itf = (Itf)pxy.bind(c);
        itf.printSth("Hello");
    }

}
复制代码

 

 

 

 

 

 

 

java动态代理有一定局限性,需要定义至少一个接口,使用cglib则不必如此。
自:https://www.cnblogs.com/flying607/p/3464268.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值