0x00 静态代理
概述
示例
对象
1 2 3
| public class Student { String name; }
|
接口类
1 2 3
| public interface StudentService { public void findName(); }
|
实现类、被代理类
1 2 3 4 5 6
| public class StudentServiceImpl implements StudentService{ @Override public void findName() { System.out.println("正在查询"); } }
|
代理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class StudentServiceImplProxy implements StudentService{ private StudentServiceImpl studentService; public StudentServiceImplProxy(StudentServiceImpl studentService) { this.studentService = studentService; }
public void deleteName(){ System.out.println("删除学生"); }
@Override public void findName() { studentService.findName(); deleteName(); } }
|
测试类
1 2 3 4 5 6 7 8 9 10
| public class TestProxy { @Test public void testProxy(){ StudentServiceImpl studentService = new StudentServiceImpl();
StudentServiceImplProxy studentServiceImplProxy = new StudentServiceImplProxy(studentService); studentServiceImplProxy.findName(); } }
|
缺点
- 不利于代码拓展,比如接口中新添加一个抽象方法时,所有实现类都需要重新实现,否则报错。
- 代理对象需要创建很多。
0x01 动态代理
概述
示例
接口类
1 2 3
| public interface RentService { public void rent(); }
|
实现类
1 2 3 4 5
| public class RentServiceImpl implements RentService { public void rent() { System.out.println("房屋出租"); } }
|
代理类
Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
是 JDK 提供的一个方法,用于创建动态代理对象,拦截和处理方法调用,并可以在调用前后添加自定义的逻辑。返回一个实现了指定接口的代理对象。该代理对象会将方法调用转发给指定的 InvocationHandler
对象,并由 InvocationHandler
来处理方法调用的逻辑。这样,我们就可以在方法调用前后进行一些自定义的处理或附加操作。
用于定义代理类的类加载器。(用代理类的加载器就行)
代理类需要实现的接口列表。
一个实现了 InvocationHandler
接口的对象,用于拦截方法调用并定义代理逻辑。
invoke(Object proxy, Method method, Object[] args)
我们可以在 invoke()
方法内部编写处理逻辑,比如在调用目标方法之前做一些额外的处理,或者根据方法名或参数类型来进行特定的操作。然后,可以通过反射机制调用真实对象的方法,完成方法调用的转发。最后,还可以通过返回值来处理方法调用的结果。需要注意的是,invoke()
方法的返回值是 Object
类型,表示被调用方法的返回值。如果被调用的方法是一个 void
方法,则 invoke()
方法的返回值应为 null
。
表示动态代理生成的代理对象。在 invoke()
方法中,如果需要调用代理对象的方法,可以使用这个参数
表示被调用的方法对象。通过这个参数,可以获取方法名、参数列表等方法相关的信息。
表示方法的参数列表。它是一个数组,包含了方法调用时传入的实际参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class RentServiceImplProxy { private RentService rentService;
public RentServiceImplProxy(RentService rentService) { this.rentService = rentService; }
public RentService creatProxy() { InvocationHandler invocationHandler = new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); Object invoke = method.invoke(rentService, args); fare(); return invoke; } };
RentService proxyInstance = (RentService)Proxy.newProxyInstance(RentServiceImplProxy.class.getClassLoader(), new Class[]{RentService.class}, invocationHandler); return proxyInstance; }
public void seeHouse(){ System.out.println("带房客看房"); } public void fare(){ System.out.println("收中介费"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class RentServiceImplProxy implements InvocationHandler { private RentService rentService;
public RentServiceImplProxy(RentService rentService) { this.rentService = rentService; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); Object result = method.invoke(rentService, args); fare(); return result; }
public void seeHouse(){ System.out.println("带房客看房"); } public void fare(){ System.out.println("收中介费"); } public Object creatProxy() { Object p = Proxy.newProxyInstance(RentServiceImplProxy.class.getClassLoader(), new Class[]{RentService.class}, this ); return p; } }
|
测试类
1 2 3 4 5 6 7 8 9 10 11 12
| public class TestProxy { @Test public void testProxy(){ RentServiceImpl rentService = new RentServiceImpl();
RentServiceImplProxy rentServiceImplProxy = new RentServiceImplProxy(rentService); RentService rentService1 = (RentService) rentServiceImplProxy.creatProxy(); rentService1.rent(); } }
|