在Java里头,动态代理就是个牛逼的机制,让你能够在运行时创造和使用代理对象。这些代理对象能够拦截并处理目标对象的方法调用。它们是在内存里头动态生成的,不是事先写好的。
作用一:增强目标对象功能 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动态代理的作用。它可以让你以一种灵活而强大的方式处理对象行为,并实现增强、横切关注点和统一管理等功能。