java 为什么要搞动态代理呢?
ava中使用动态代理的主要目的是实现面向切面编程(Aspect-Oriented Programming,AOP)。AOP是一种编程范式,它将系统的关注点分离,使得开发者能够更加专注于业务逻辑而不必过多考虑与之相关的横切关注点(cross-cutting concerns),例如日志记录、性能监测、事务管理等。
动态代理允许在运行时创建代理对象,这些代理对象可以拦截并处理被代理对象的方法调用。通过动态代理,我们可以将横切关注点的代码从业务逻辑代码中抽离出来,从而实现了关注点的分离。
下面是一个简单的示例代码,演示了如何使用动态代理实现简单的日志记录功能。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Calculator {
int add(int a, int b);
}
class CalculatorImpl implements Calculator {
@Override
public int add(int a, int b) {
return a + b;
}
}
class LoggingProxy implements InvocationHandler {
private Object target;
public LoggingProxy(Object target) {
this.target = target;
}
@Override
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 sum = proxy.add(3, 4);
System.out.println("Result: " + sum);
}
}
在上述代码中,我们定义了一个接口Calculator
,并实现了它的一个具体类CalculatorImpl
。然后,我们创建了一个名为LoggingProxy
的动态代理类,它实现了InvocationHandler
接口。在invoke
方法中,我们在调用被代理对象的方法之前和之后添加了日志记录的逻辑。
在Main
类的main
方法中,我们首先创建了一个CalculatorImpl
对象作为被代理对象。然后,通过Proxy.newProxyInstance
方法创建了一个代理对象proxy
,并指定了代理对象的类加载器、实现的接口以及LoggingProxy
作为代理对象的InvocationHandler
。最后,我们通过代理对象调用add
方法,并观察控制台输出的日志记录。
通过动态代理,我们可以在不修改原有业务逻辑代码的情况下,很方便地添加各种横切关注点的处理逻辑。这样可以提高代码的可维护性、可扩展性和可重用性,同时减少代码的重复性。