动态代理实现代码

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。动态代理实现代码,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

代理模式是当我们要调用某个目标方法时,不直接调用这个方法,而是通过调用某个代理类中的方法来实现目标方法调用;这样就可以在调用目标方法前后执行一些特定方法,来实现目标方法的增强。
代理模式可以分为静态代理和动态代理两种,静态代理就是在编码时已经确认了委托类和代理类的关系;动态代理是使用反射和字节码的技术,在运行期创建指定接口或类的子类,以及实例对象的技术。
在java中实现代理有两种技术:如果目标类实现了接口,就可以使用JDK中的Proxy实现动态代理;如果目标类没有实现接口,需要使用cglib实现代理,cglib是基于ASM的字节码生成库,允许在运行时对字节码进行修改和动态生成。
下面演示这两种方式实现的代理:
工程中需要引入cglib项目坐标,如果项目中使用了spring框架,就不需要这个项目坐标,因为在spring中已经集成了cglib项目。

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

下面的是目标类和它对应的接口:

/**
 * @createDate: 2023/6/29
 */
public interface MyTarget {

    /**
     * 目标方法执行
     */
    void runMethod();
}

/**
 * @createDate: 2023/6/29
 */
public class MyTargetImpl implements MyTarget {

    @Override
    public void runMethod() {
        System.out.println("目标类方法执行....");
    }
}

增强类和对应的方法如下,希望在执行目标类中的方法前后分别执行对应增强类中的方法:

/**
 * @createDate: 2023/6/29
 */
public class MyAdvice {

    public void before() {
        System.out.println("前置方法执行....");
    }

    public void after() {
        System.out.println("后置方法执行....");
    }
}

接下来演示分别使用proxy和cglib两种代理方式实现的动态代理:
使用jdk中的Proxy代理实现代码如下:

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

/**
 * @createDate: 2023/6/29
 */
public class ProxyTest {

    public static void main(String[] args) {
        // 实例化对象
        MyAdvice myAdvice = new MyAdvice();
        MyTargetImpl myTarget = new MyTargetImpl();

        // 构建代理对象
        final Object proxy = Proxy.newProxyInstance(myTarget.getClass().getClassLoader(), myTarget.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                myAdvice.before();
                final Object result = method.invoke(myTarget, args);
                myAdvice.after();
                return result;
            }
        });

        // 强转为实现类的接口,并执行方法
        MyTarget proxyObj = (MyTarget) proxy;
        proxyObj.runMethod();

    }
}

使用cglib代理实现代码如下:

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @createDate: 2023/6/29
 */
public class CglibTest {

    public static void main(String[] args) {
        // 实例化对象
        MyAdvice myAdvice = new MyAdvice();
        MyTargetImpl myTarget = new MyTargetImpl();

        Enhancer enhancer = new Enhancer();
        // 设置父类,这样生成的代理对象就是这个类的子类
        enhancer.setSuperclass(MyTargetImpl.class);
        // 设置回调,这样执行代理对象的方法时最终就会调用到这里的方法
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                myAdvice.before();
                final Object invoke = method.invoke(myTarget, objects);
                myAdvice.after();

                return invoke;
            }
        });
        final MyTargetImpl proxy = (MyTargetImpl) enhancer.create();

        proxy.runMethod();
    }
}

上面就演示了两种使用代理模式的代码,虽然比较简单却演示了在框架中实现代理类的原理,只不过框架中会通过配置文件方式或注解标签方式更灵活的实现代理功能,但是翻看源码,最后都会走到如上的代理代码。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/181869.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!