动态代理的两种实现方式
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>
public class Test { public static void main(String[] args) { Student stu = new Student(); /*stu.eat("米饭"); stu.study();*/ Object proxyStu = Enhancer.create(stu.getClass(), new MethodInterceptor() { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { if (method.getName().equals("study")) { System.out.println("来大学学习"); return null; } else { return method.invoke(stu, args); } } } proxyStu.eat("米饭"); proxyStu.study(); } }
与jdk动态代理相比,CGLIB不要求必须要实现接口StudentInterface ,就能直接对目标对象就行代理增强,更加的简单方便。