动态代理介绍
1.概念
动态代理是指动态的在内存中构建代理对象,动态是相对于静态代理而言的。
有两个重要特点:
- 动态的
- 内存中构建
- 实现方式
- jdk动态代理
- cglib动态代理
jdk动态代理的概念
- 代理类在程序调用到代理类对象时才由JVM真正创建
- 通过反射类Proxy以及InvocationHandler回调接口实现的
- 基于反射机制,JVM根据传进来的业务实现类对象以及 方法名 ,动态地创建了一个 代理类的class文件并被字节码引擎执行,然后通过该代理类对象进行方法调用。
- 我们需要做的,只需指定代理类的预处理、调用后操作即可。
jdk动态代理的组成
- 业务接口
- 业务实现类, 负责实现主要的业务方法
- 调用处理器,实现调用管理接口InvocationHandler创建动态代理类
案例演示
-
业务接口(同静态代理)
-
业务实现类(同静态代理)
-
调用处理器
public class JDKProxy implements InvocationHandler { private Object target;//真正的业务实现类对象,用来调用具体的业务方法 /** * 绑定业务对象并返回一个代理类 */ public Object bind(Object target) { this.target = target; //接收业务实现类对象参数 //通过反射机制,创建一个代理类对象实例并返回。用户进行方法调用时使用 //创建代理对象时,需要传递该业务类的类加载器(用来获取业务实现类的元数据, // 在包装方法是调用真正的业务方法)、接口、handler实现类 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } /** * 包装调用方法:进行预处理、调用后处理 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("预处理操作——————"); //调用真正的业务方法 result = method.invoke(target, args); System.out.println("调用后处理——————"); return result; } }
-
业务调用
public class JDKProxyApplication { public static void main(String[] args) { IAccountService accountService = new AccountServiceImpl(); JDKProxy proxy = new JDKProxy(); IAccountService accountServiceProxy = (IAccountService) proxy.bind(accountService); accountServiceProxy.queryAccount(); accountServiceProxy.updateAccount(); } }
jdk动态代理特点及问题分析
- 特点分析
- jdk动态代理需要使用业务实现类所实现的接口作为参数。
- 问题分析
- 如果业务实现类是没有实现接口而是直接定义业务方法的话,就无法使用jdk动态代理了。
- 如果业务实现类中新增了接口中没有的方法,这些方法是无法被代理的。
网友评论