动态代理是使用反射机制对目标对象进行扩展,在运行时动态创建代理对象,从而实现对目标对象的增强。 Java有两种动态代理方式:
public interface Hello {
void sayHello();
void sayBye();
}
public class HelloImpl implements Hello {
@Override
public void sayHello() {
System.out.println("Hello World!");
}
@Override
public void sayBye() {
System.out.println("Bye Bye!");
}
}
定义一个InvocationHandler实现类,并在invoke方法中对目标方法进行增强:
可以判断方法名,不对sayBye方法增强,直接返回
public class InvocationHandler implements java.lang.reflect.InvocationHandler {
private Object target;
public InvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable {
if (method.getName().equals("sayBye")) {
return method.invoke(target, args);
}
System.out.println("Before");
Object result = method.invoke(target, args);
System.out.println("After");
return result;
}
}
最后使用Proxy.newProxyInstance方法创建代理对象
public class Main {
public static void main(String[] args) {
Hello hello = new HelloImpl();
InvocationHandler handler = new InvocationHandler(hello);
Hello proxy = (Hello) Proxy.newProxyInstance(hello.getClass().getClassLoader(), hello.getClass().getInterfaces(), handler);
proxy.sayHello();
proxy.sayBye();
}
}
使用proxy对象调用方法时,会经过MyInvocationHandler的invoke方法进行增强,从而实现动态代理的效果。 这就是Java基于接口的动态代理实现原理,CGLIB原理类似,只是不依赖接口,直接对目标类进行子类化代理。
public class Hello {
public void sayHello() {
System.out.println("Hello World!");
}
}
定义一个MethodInterceptor实现类,用于增强目标方法
public class HelloMethodInterceptor implements org.springframework.cglib.proxy.MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("Before");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("After");
return result;
}
}