JDK动态代理

2023-09-21 09:58:57

Java中的两种常用动态代理方式

JDK动态代理和Cglib动态代理是Java中常用的实现动态代理的方式。它们都可以在运行时生成代理类,实现对目标对象的代理操作。

JDK动态代理适用于接口代理,Cglib动态代理适用于类代理。

Cglib动态代理

Cglib动态代理是基于继承的动态代理方式。它通过生成目标类的子类来实现代理,子类重写了目标类的方法,并在方法中添加了代理逻辑。


JDK动态代理

JDK动态代理是Java提供的一种基于接口的动态代理方式。它通过反射机制在运行时动态生成代理类,代理类实现了目标接口,并且将方法的调用委托给InvocationHandler接口的实现类来处理。

  1. 基于接口的动态代理示例代码:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 定义接口
interface Hello {
    void sayHello();
}

// 实现接口的类
class HelloImpl implements Hello {
    @Override
    public void sayHello() {
        System.out.println("Hello, World!");
    }
}

// 实现InvocationHandler接口
class DynamicProxy implements InvocationHandler {
    private Object target;

    public DynamicProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method invocation");
        Object result = method.invoke(target, args);
        System.out.println("After method invocation");
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        Hello hello = new HelloImpl();
        InvocationHandler handler = new DynamicProxy(hello);
        Hello proxy = (Hello) Proxy.newProxyInstance(
                hello.getClass().getClassLoader(),
                hello.getClass().getInterfaces(),
                handler);
        proxy.sayHello();
    }
}
  1. 基于类的动态代理示例代码:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 定义类
class Hello {
    public void sayHello() {
        System.out.println("Hello, World!");
    }
}

// 实现InvocationHandler接口
class DynamicProxy implements InvocationHandler {
    private Object target;

    public DynamicProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method invocation");
        Object result = method.invoke(target, args);
        System.out.println("After method invocation");
        return result;
    }
}

public class Main {
    public static void main(String[] args) {
        Hello hello = new Hello();
        InvocationHandler handler = new DynamicProxy(hello);
        Hello proxy = (Hello) Proxy.newProxyInstance(
                hello.getClass().getClassLoader(),
                hello.getClass().getInterfaces(),
                handler);
        proxy.sayHello();
    }
}

Java动态代理中,通过Proxy.newProxyInstance()方法创建代理对象时,需传三个参数:

  1. 类加载器(ClassLoader):用来加载目标类和代理类的类加载器。一般情况下,可以使用目标类的类加载器来加载代理类。

  2. 接口数组(Class<?>[] interfaces):代理类需要实现的接口数组。代理对象会实现这些接口,并且可以调用接口中定义的方法。

  3. 调用处理器(InvocationHandler):一个实现了InvocationHandler接口的对象,用来处理代理对象的方法调用。在调用代理对象的方法时,会触发调用处理器的invoke()方法。

第一个参数的类加载器可以传递目标类的类加载器,也可以传递实现了 InvocationHandler 接口的对象的类加载器。但是,为了确保代理类能够访问目标类的方法和属性,通常建议传递目标类的类加载器。

如果接口没有实现类时,该使用场景为,工具类中提供了注解,在服务的接口的方法上,通过使用工具类中的注解就能执行接口方法,而不需要定义接口的实现类。

//服务中有接口
public interface AInter {
	public void insetStudent(Student stu);
}
//如何想要AInter能被代理,可把AInter注入到spring中,返回值为代理后的对象,这样@Autowire拿到的就是代理对象,调用AInter中的方法时,走的就是代理对象里面的逻辑

//配置类
@Configuration
public class Config {
	@Bean
	public AInter doProxy () {
		return Util.myProxy(AInter.class)l
	}
}

//service层
pubic class StuService {
	@Autowire
	AInter aInter;
}


------------------------------------------------------
//工具类 
public class Util() {
	public <T> T myProxy(Class<T> classPro){
	MyHandle handler = new MyHandle(classPro);
	 T proxy = (T) Proxy.newProxyInstance(
	                handler.getClass().getClassLoader(),
	                new Class<?>[] {classPro},
	                handler);
	}
	return proxy;
}

//实现InvocationHandler接口的类
public class MyHandle implements InvocationHandler{
   private Type target;

    public MyHandle(Type target) {
        this.target = target;
    }
}

第一个参数可传入实现了InvocationHandler接口的对象类加载器,第二个参数可直接传入这个接口的数组,第三个参数传实现InvocationHandler接口的对象。

更多推荐

生信分析Python实战练习 9 | 视频27

开源生信Python教程生信专用简明Python文字和视频教程源码在:https://github.com/Tong-Chen/Bioinfo_course_python目录背景介绍编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Pyt

Springboot部署服务器项目上线

第一步,项目打包,有两种方式第一种、直接在项目根目录打开终端,输入以下语句即可。如下图:mvncleanpackage-DskipTests第二种、在右侧点击Maven选项,选择鼠标左键双击package选项即可。如下图:两种方法的结果,都会得到我们需要jar包,效果如下图:(可选项)如果觉得jar包名太难记,还可以在

“Vue进阶:深入理解插值、指令、过滤器、计算属性和监听器“

目录引言:Vue的插值Vue的指令Vue的过滤器Vue的计算属性和监听器vue购物车案例总结:引言:Vue.js是一款流行的JavaScript框架,它提供了许多强大的功能来简化前端开发。在本篇博客中,我们将深入探讨Vue的一些高级特性,包括插值、指令、过滤器、计算属性和监听器。通过理解和灵活运用这些功能,我们可以更好

10个值得关注的学习网站,知乎超30万人收藏,什么资源都可找到!

hi,大家好我是技术苟,每周准时上线为你带来实用黑科技!由于公众号改版,现在的公众号消息已经不再按照时间顺序排送了。因此小伙伴们就很容易错过精彩内容。喜欢黑科技的小伙伴,可以将黑科技百科公众号设为标星,这样就不会走丢啦~免责声明hello,朋友们,黑科技百科所有资源均为免费分享,绝多部分来源于互联网,所有资源仅提供学习

线程的方法(未完成)

线程的方法1.获取当前线程对象:CurrentThread()@Testpublicvoidbb(){Threadthread=Thread.currentThread();System.out.println(thread.getName());//打印main}2.currentThread().setName和c

CPP-Templates-2nd--第 21 章 模板和继承

目录21.1空基类优化(TheEmptyBaseClassOptimization,EBCO)21.1.1布局原则21.1.2将数据成员实现为基类21.2TheCuriouslyRecurringTemplatePattern(CRTP)21.2.1TheBarton-NackmanTrick21.2.2运算符的实现(

客户端和服务端信息交互模型

什么是客户端和服务端?客户端:可以向服务器发请求,并接收返回的内容进行处理服务器端:能够接收客户端请求,并且把相关资源信息返回给客户端的当用户在地址栏中输入网址,到最后看到页面,中间都经历了什么?后面会详细解析每个步骤干的事一、URL地址解析A:URI/URL/URNURI(UniformResourceldentif

云服务部署:AWS、Azure和GCP比较

🌷🍁博主猫头虎(🐅🐾)带您GotoNewWorld✨🍁🦄博客首页——🐅🐾猫头虎的博客🎐🐳《面试题大全专栏》🦕文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》🐾学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》🐅学会Gol

【腾讯云 Cloud Studio 实战训练营】提升开发效率与协作:探索腾讯云 Cloud Studio 的强大功能与优势

文章目录一、前言二、认识腾讯云CloudStudio2.1什么是云端开发环境2.2CDE的特点与优点2.2.1提高效率,开发环境一键运行2.2.2提高生产力,可以并行的工作2.2.3开发更加规范2.2.4提供监管,降低资本与资源2.3云端开发环境具备的四大要素2.4腾讯云CloudStudio强大的AI功能2.4.1与

tauri vue vite elemrntui

tauri+vue+viterust```根据https://www.rust-lang.org/tools/install,安装rust。如果是windows会跳出vs工具的安装器,会自动勾选要安装的,直接点安装即可执行cargo--version检查安装是否完成,可以使用cargo创建一个hello项目验证rust

OpenCV中的HoughLines函数和HoughLinesP函数到底有什么区别?

一、简述基于OpenCV进行直线检测可以使用HoughLines和HoughLinesP函数完成的。这两个函数之间的唯一区别在于,第一个函数使用标准霍夫变换,第二个函数使用概率霍夫变换(因此名称为P)。概率版本之所以如此,是因为它仅分析点的子集并估计这些点都属于同一条线的概率。此实现是标准霍夫变换的优化版本,在这种情况

热文推荐