使用泛型简化动态代理
说明##
- 本文适合对动态代理有最最基本了解的人,可参看AOP的底层实现-CGLIB动态代理和JDK动态代理。
- 本文目的在于简化动态代理的调用
maven依赖##
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.5</version>
</dependency>
类图##
代码##
Shape###
public interface Shape {
void draw();
}
Circle###
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("我是一个圆~");
}
}
Square###
public class Square implements Shape{
@Override
public void draw() {
System.out.println("我是一个四方形~");
}
}
DynamicProxy###
public interface DynamicProxy<T> {
T bind();
}
JDKDynamicProxy###
public class JDKDynamicProxy<T> implements DynamicProxy<T>, InvocationHandler {
public JDKDynamicProxy(T t) {
this.t = t;
}
private T t;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method " + method.getName() + " begin");
method.invoke(t, args);
System.out.println("method " + method.getName() + " end");
return null;
}
@Override
public T bind() {
return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), this);
}
}
CGLibDynamicProxy###
public class CGLibDynamicProxy<T> implements DynamicProxy<T>, MethodInterceptor {
private T t;
public CGLibDynamicProxy(T t) {
this.t = t;
}
public T bind() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(t.getClass());
enhancer.setCallback(this);
T t = (T) enhancer.create();
return t;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("method " + method.getName() + " begin");
// methodProxy.invokeSuper(o, objects);
method.invoke(t,objects);
System.out.println("method " + method.getName() + " end");
return null;
}
}
Demo###
public class Demo {
public static void main(String[] args) {
Shape shape = new Circle();
CGLibDynamicProxy<Shape> cgLibDynamicProxy = new CGLibDynamicProxy<>(shape);
cgLibDynamicProxy.bind().draw();
shape = new Square();
JDKDynamicProxy<Shape> jdkDynamicProxy = new JDKDynamicProxy<>(shape);
jdkDynamicProxy.bind().draw();
}
}
运行结果##
注意##
cglib中使用methodProxy和method可以达到同样的效果,但是所调参数不一样,否则会报错,具体原因无意深究,会用即可。
God, Grant me the SERENITY, to accept the things I cannot change,
COURAGE to change the things I can, and the WISDOM to know the difference.