1、动态代理介绍

动态代理:在不改变目标对象方法的情况下对方法进行增强

组成:

* 被代理对象:真实的对象
* 代理对象:内存中的对象
要求:代理对象必须和被代理对象实现相同的接口

代理的实现方式有两种:(1)jdk动态代理;(2)CGLIB动态代理(这个是第三方实现的,所以使用这种方式,我们要引入jar包)

2、代码准备

StudentInterface接口代码
public interface StudentInterface { void eat(String name); void study(); }
Student代码
public class Student implements StudentInterface{ public void eat(String name)
{ System.out.println("学生吃" + name); } public void study() {
System.out.println("在家自学"); } }
Test代码
public class Test { public static void main(String[] args) { Student stu = new
Student(); stu.eat("米饭"); stu.study(); } }
3、要求

要求:在不改动Student类中任何的代码的前提下,通过study方法输出一句话:来大学学习。

4、方法一:使用jdk动态代理
public class Test { public static void main(String[] args) { Student stu = new
Student(); /*stu.eat("米饭"); stu.study();*/ /* 类加载器:和被代理对象使用相同的类加载器
接口类型Class数组:和被代理对象使用相同接口 代理规则:完成代理增强的功能 */ StudentInterface proxyStu =
(StudentInterface) Proxy.newProxyInstance(stu.getClass().getClassLoader(), new
Class[]{StudentInterface.class}, new InvocationHandler() { /*
执行Student类中所有的方法都会经过invoke方法 对method方法进行判断 如果是study,则对其增强 如果不是,还调用学生对象原有的功能即可
*/ @Override public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable { if(method.getName().equals("study")) {
System.out.println("来大学学习"); return null; }else { return
method.invoke(stu,args); } } }); proxyStu.eat("米饭"); proxyStu.study(); } }
5、方式二:使用CGLIB动态代理

CGLIB jar的maven坐标
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId>
<version>2.1_2</version> </dependency> package com.example; 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 Test { public static void main(String[] args) { Student stu = new
Student(); /*stu.eat("米饭"); stu.study();*/ // 生成的代理对象 Student proxyStu =
(Student) Enhancer.create(stu.getClass(), new 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 { if
(method.getName().equals("study")) { System.out.println("来大学学习");
method.invoke(stu, objects); return null; } else { return method.invoke(stu,
objects); } } }); proxyStu.eat("米饭"); proxyStu.study(); } }
与jdk动态代理相比,CGLIB不要求必须要实现接口StudentInterface ,就能直接对目标对象就行代理增强,更加的简单方便。

技术
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:766591547
关注微信