java中的动态代理与责任链模式详解

 更新时间:2023年08月28日 10:20:39   作者:等後那场雪  
这篇文章主要介绍了java中的动态代理与责任链模式详解,动态代理提供了一种灵活且非侵入式的方式,可以对对象的行为进行定制和扩展,它在代码重用、解耦和业务逻辑分离、性能优化以及系统架构中起到了重要的作用,需要的朋友可以参考下

动态代理

动态代理是一种设计模式,它允许在运行时创建代理对象,并将方法调用重定向到不同的实际对象。

它使我们能够在不修改现有代码的情况下增加或改变某个对象的行为。

jdk动态代理

被代理接口: 

package com.mzs.test;
public interface DemoService {
    void speak(String str);
    void jump(String str);
}

被代理类: 

package com.mzs.test;
public class DemoServiceImpl implements DemoService {
    public void speak(String string) {
        System.out.println("hello " + string);
    }
    public void jump(String string) {
        System.out.println("hi " + string);
    }
}

代理类: 

package com.mzs.test;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TestProxy implements InvocationHandler {
    private Object target;
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(target, args);
    }
    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
}

 测试方法:

package com.mzs.test;
public class TestProxyDemo {
    public static void main(String[] args) {
        TestProxy instance = new TestProxy();
        DemoService proxy = (DemoService) instance.bind(new DemoServiceImpl());
        proxy.speak("tom");
    }
}

cglib动态代理

被代理的类:

package com.mzs.test;
public class DemoServiceImpl {
    public void speak(String string) {
        System.out.println("hello " + string);
    }
    public void jump(String string) {
        System.out.println("hi " + string);
    }
}

代理类: 

package com.mzs.test;
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 TestProxy implements MethodInterceptor {
    /**
     * 代理逻辑方法
     *
     * @param o 代理对象
     * @param method 方法
     * @param objects 方法参数
     * @param methodProxy 代理方法
     * @return 方法返回值
     * @throws Throwable 异常
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        return methodProxy.invokeSuper(o, objects);
    }
    /**
     * 生成代理对象
     *
     * @param cls 被代理的Class对象
     * @return 代理对象
     */
    public Object bind(Class cls) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(cls);
        enhancer.setCallback(this);
        return enhancer.create();
    }
}

测试方法:

package com.mzs.test;
public class TestProxyDemo {
    public static void main(String[] args) {
        TestProxy instance = new TestProxy();
        DemoServiceImpl proxy = (DemoServiceImpl) instance.bind(DemoServiceImpl.class);
        proxy.jump("tom");
        proxy.speak("selina");
    }
}

注:导入的依赖,如下:

<!-- cglib proxy -->
<dependency>
  <groupId>cglib</groupId>
  <artifactId>cglib</artifactId>
  <version>2.2.2</version>
</dependency>
<dependency>
  <groupId>asm</groupId>
  <artifactId>asm</artifactId>
  <version>3.3</version>
</dependency>

两者的特点

  • jdk动态代理,使用反射生成实现接口的代理类,被代理类需要实现接口,效率比jdk动态代理高。
  • cglib动态代理,使用asm字节技术生成代理类,继承被代理类,并覆盖并加强父类的方法。 

责任链模式

package com.mzs.testThread1;
public interface UserService {
	void speak(String str);
}
package com.mzs.testThread1;
public class UserServiceImpl implements UserService {
	@Override
	public void speak(String str) {
		System.out.println(str);
	}
}

 MyInterceptor2、MyInterceptor3都一样: (除了1变成2或者3)

package com.mzs.testThread1;
import java.lang.reflect.Method;
public class MyInterceptor implements Interceptor {
	@Override
	public boolean before(Object proxy, Object target, Method method, Object[] args) {
		System.out.println("反射方法前逻辑1");
		return true;
	}
	@Override
	public void around(Object proxy, Object target, Method method, Object[] args) {
		System.out.println("取代被代理对象的方法");
	}
	@Override
	public void after(Object proxy, Object target, Method method, Object[] args) {
		System.out.println("反射方法后逻辑1");
	}
}
package com.mzs.testThread1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class InterceptorProxy implements InvocationHandler {
	private Object target;
	private Interceptor interceptor;
	public InterceptorProxy(Object target, Interceptor interceptor) {
		this.target = target;
		this.interceptor = interceptor;
	}
	public static Object bind(Object target, Interceptor interceptor) {
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InterceptorProxy(target, interceptor));
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object result = null;
		if (interceptor == null)
			result = method.invoke(target, args);
		if (interceptor.before(proxy, target, method, args)) 
			result = method.invoke(target, args);
		else 
			interceptor.around(proxy, target, method, args);
		interceptor.after(proxy, target, method, args);
		return result;
	}
}

测试方法:

package com.mzs.testThread1;
public class TestDemo {
	public static void main(String[] args) {
		UserService proxy1 = (UserService) InterceptorProxy.bind(new UserServiceImpl(), new MyInterceptor());
		UserService proxy2 = (UserService) InterceptorProxy.bind(proxy1, new MyInterceptor2());
		UserService proxy3 = (UserService) InterceptorProxy.bind(proxy2, new MyInterceptor3());
		proxy3.speak("hello");
	}
}

控制台输出如下: 

反射方法前逻辑3
反射方法前逻辑2
反射方法前逻辑1
hello
反射方法后逻辑1
反射方法后逻辑2
反射方法后逻辑3

到此这篇关于java中的动态代理与责任链模式详解的文章就介绍到这了,更多相关java动态代理与责任链内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java多线程 CompletionService

    Java多线程 CompletionService

    这篇文章主要介绍了Java多线程 CompletionService,CompletionService用于提交一组Callable任务,其take方法返回已完成的一个Callable任务对应的Future对象,需要的朋友可以参考一下文章详细内容
    2021-10-10
  • java的三种IO模型详解(BIO、NIO、AIO)

    java的三种IO模型详解(BIO、NIO、AIO)

    本文介绍了BIO、NIO和AIO三种不同的IO模型,分别分析了它们的工作机制、实现方式以及与BIO的对比,BIO是阻塞的,每个连接需要一个线程;NIO是同步非阻塞的,通过缓冲区和选择器实现I/O多路复用;AIO是异步的,操作系统处理IO操作,完成后通知应用程序
    2024-11-11
  • Json字符串转Java对象和List代码实例

    Json字符串转Java对象和List代码实例

    这篇文章主要介绍了Json字符串转Java对象和List代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • springboot打jar包之后下载文件的路径问题

    springboot打jar包之后下载文件的路径问题

    这篇文章主要介绍了springboot打jar包之后下载文件的路径问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 详解springmvc如何处理接受http请求

    详解springmvc如何处理接受http请求

    这篇文章主要给大家介绍了springmvc如何处理接受http请求,文中通过代码示例给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-02-02
  • 深入理解java.lang.String类的不可变性

    深入理解java.lang.String类的不可变性

    不可变类只是其实例不能被修改的类。每个实例中包含的所有信息都必须在创建该实例的时候就提供,并且在对象的整个生命周期内固定不变,感兴趣的可以了解一下
    2021-06-06
  • SpringBoot实现文件上传接口

    SpringBoot实现文件上传接口

    这篇文章主要为大家详细介绍了SpringBoot实现文件上传接口,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-11-11
  • Java流程控制顺序结构原理解析

    Java流程控制顺序结构原理解析

    这篇文章主要介绍了Java流程控制顺序结构原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • SpringBoot自动配置与启动流程详细分析

    SpringBoot自动配置与启动流程详细分析

    这篇文章主要介绍了SpringBoot自动配置原理分析,SpringBoot是我们经常使用的框架,那么你能不能针对SpringBoot实现自动配置做一个详细的介绍。如果可以的话,能不能画一下实现自动配置的流程图。牵扯到哪些关键类,以及哪些关键点
    2022-11-11
  • SpringBoot整合Elasticsearch游标查询的示例代码(scroll)

    SpringBoot整合Elasticsearch游标查询的示例代码(scroll)

    这篇文章主要介绍了SpringBoot整合Elasticsearch游标查询(scroll),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10

最新评论