Java 动态代理作用是什么?(很详细)

116 阅读3分钟

在Java里头,动态代理就是个牛逼的机制,让你能够在运行时创造和使用代理对象。这些代理对象能够拦截并处理目标对象的方法调用。它们是在内存里头动态生成的,不是事先写好的。

截图20231019162648.png

作用一:增强目标对象功能 Java动态代理就像给目标对象穿上了超级战甲一样,能够增强它们的功能。来看个例子吧:

interface Calculator { int add(int a, int b); } class CalculatorImpl implements Calculator { public int add(int a, int b) { return a + b; } }

class LoggingProxy implements InvocationHandler { private Object target;

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

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(“Before method: ” + method.getName()); Object result = method.invoke(target, args); System.out.println(“After method: ” + method.getName()); return result; } }

public class Main { public static void main(String[] args) { Calculator calculator = new CalculatorImpl(); Calculator proxy = (Calculator) Proxy.newProxyInstance( calculator.getClass().getClassLoader(), calculator.getClass().getInterfaces(), new LoggingProxy(calculator) );

int result = proxy.add(2, 3); System.out.println(“Result: ” + result); } } 在这个例子里,我们有一个Calculator接口和它的实现类CalculatorImpl。我们想要在调用add方法之前和之后打印日志。为了达到这个目的,我们创造了一个叫做LoggingProxy的代理类,实现了InvocationHandler接口。当代理对象的方法被调用时,我们可以在里面加入额外的逻辑。通过使用Java动态代理,我们能够把日志记录逻辑和目标对象的实现分离开来,在运行时动态生成代理对象。

作用二:实现横切关注点 Java动态代理还能够像超级英雄一样实现横切关注点。看个例子:

interface UserService { void saveUser(User user); }

class UserServiceImpl implements UserService { public void saveUser(User user) { // 保存用户到数据库 } }

class TransactionProxy implements InvocationHandler { private Object target;

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

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 开启事务 System.out.println(“Start transaction”);

Object result = method.invoke(target, args);

// 提交事务 System.out.println(“Commit transaction”);

return result; } }

public class Main { public static void main(String[] args) { UserService userService = new UserServiceImpl(); UserService proxy = (UserService) Proxy.newProxyInstance( userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new TransactionProxy(userService) );

User user = new User(“John”); proxy.saveUser(user); } } 在这个例子里,我们有一个UserService接口和它的实现类UserServiceImpl。我们想要在保存用户之前和之后执行事务管理。为了达到这个目的,我们创造了一个叫做TransactionProxy的代理类,实现了InvocationHandler接口。当代理对象的方法被调用时,我们可以在里面加入事务管理逻辑。通过使用Java动态代理,我们能够把事务管理逻辑和目标对象的实现分离开来,并将其作为一个横切关注点应用于多个对象。

作用三:实现代理对象的统一管理 Java动态代理还能够像团队经理一样统一管理代理对象。看个例子:

class Image { // 加载和显示图像 }

class ImageProxy implements Image { private String filename; private Image image;

public ImageProxy(String filename) { this.filename = filename; }

public void display() { if (image == null) { image = new Image(filename); } image.display(); } }

public class Main { public static void main(String[] args) { List images = new ArrayList<>();

// 添加多个图片代理对象到列表里头 images.add(new ImageProxy(“image1.jpg”)); images.add(new ImageProxy(“image2.jpg”)); images.add(new ImageProxy(“image3.jpg”));

// 统一管理代理对象,调用display方法时才加载和显示图像 for (Image image : images) { image.display(); } } } 在这个例子里,我们有一个Image类和它的实现类ImageProxy。代理对象只有在第一次调用display方法时才会加载和显示图像。通过使用Java动态代理,我们能够统一管理多个代理对象,并且只在需要的时候才实际创建和使用它们。

希望这些代码示例能够帮助你更好地理解Java动态代理的作用。它可以让你以一种灵活而强大的方式处理对象行为,并实现增强、横切关注点和统一管理等功能。