可视化与代码说明jdk动态代理与cglib动态代理--InvocationHandler--MethodInterceptor

动态代理是为了实现Aop编程(不修改类源码,类方法执行前后,自定义增强处理, 日志 拦截等等),代理的是类对象

jdk动态代理

被代理的类需要实现接口,针对接口的代理,通过生成一个实现了接口的动态类实现代理
jdk动态代理--InvocationHandler

ServiceImpl是被代理类,实现接口ServiceInterface
JDKProxy是代理处理方法类,实现接口InvocationHandler

通过JDKProxy.bind()得到jdk【动态生成】代理类ServiceProxy (ServiceInterface)
当你调用ServiceProxy.doService()会执行JDKProxy的invoke()方法,实现代理

//ServiceInterface.java
public interface ServiceInterface {
   public void doService();
}

//ServiceImpl.java
public class ServiceImpl implements ServiceInterface {
    public void doService() {
        System.out.println("ServiceImpl");
    }
}

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

public class JDKProxy implements InvocationHandler {

    private Object target = null;

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

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before method:"+method.getName());
        Object res = method.invoke(target,args);
        System.out.println("after method");
        return res;
    }

    public static void main(String[] args) {
        ServiceInterface service = (ServiceInterface) new JDKProxy().bind(new ServiceImpl());
        service.doService();
    }

}

cglib动态代理

通过生成被代理类的【子类】实现代理,所以 Cglib是无法代理final修饰的方法或类
cglib动态代理--MethodInterceptor

ServiceImpl是被代理类
ServiceProxy是代理处理类,实现接口MethodInterceptor

通过ServiceProxy.getProxy()动态生成被代理类子类ServiceImpl_SubClass (ServiceImpl)
当你调ServiceImpl_SubClass.doService()会执行ServiceProxy.Intercept()方法,实现代理

//ServiceInterface.java
public interface ServiceInterface {
    public void doService();
}

//ServiceImpl.java
public class ServiceImpl implements ServiceInterface{
    public void doService() {
        System.out.println("ServiceImpl");
    }
}

//ServiceProxy.java
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class ServiceProxy implements MethodInterceptor {

    private Enhancer enhancer = new Enhancer();

    public Object getProxy(Class clazz) {
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("before method:" + method.getName());
        Object res = methodProxy.invokeSuper(o, objects);
        System.out.println("after method");
        return res;
    }

    public static void main(String[] args) {
        ServiceInterface service = (ServiceImpl) new ServiceProxy().getProxy(ServiceImpl.class);
        service.doService();
    }
}

//pom.xml
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>

上面的jdk与cglib动态代理例子,没有改变ServiceInterface接口与ServiceImpl实现类代码,通过一个代理处理类实现动态对ServiceImpl的代理,方法执行前后增强处理,打印日志,也可以通过try catch捕获方法中的异常实现事务控制等等

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JDK动态代理CGLib动态代理都是实现AOP编程的方式,它们的使用上有以下异同点: 1. JDK动态代理只能代理实现了接口的类,而CGLib动态代理可以代理没有实现接口的类。 2. JDK动态代理是通过反射来实现的,而CGLib动态代理使用的是继承。 3. JDK动态代理在生成代理对象时,需要传入一个InvocationHandler对象,而CGLib动态代理在生成代理对象时,需要继承MethodInterceptor类,并重写intercept()方法。 4. JDK动态代理生成的代理对象性能比CGLib动态代理生成的代理对象性能要低。 下面是一个JDK动态代理的例子: ```python import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface Subject { void request(); } class RealSubject implements Subject { public void request() { System.out.println("RealSubject request"); } } class DynamicProxy implements InvocationHandler { private Object subject; public DynamicProxy(Object subject) { this.subject = subject; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before calling " + method); method.invoke(subject, args); System.out.println("after calling " + method); return null; } } public class Main { public static void main(String[] args) { RealSubject realSubject = new RealSubject(); InvocationHandler handler = new DynamicProxy(realSubject); Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler); subject.request(); } } ``` 下面是一个CGLib动态代理的例子: ```python import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; class RealSubject { public void request() { System.out.println("RealSubject request"); } } class DynamicProxy implements MethodInterceptor { private Object subject; public DynamicProxy(Object subject) { this.subject = subject; } public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("before calling " + method); proxy.invoke(subject, args); System.out.println("after calling " + method); return null; } } public class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(RealSubject.class); enhancer.setCallback(new DynamicProxy(new RealSubject())); RealSubject subject = (RealSubject) enhancer.create(); subject.request(); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值