什么是动态代理?
在聊动态代理之前,首先得先了解什么是代理以及静态代理。
代理就是在一段方法的执行前后,加上前置操作与后置操作,常见做法有例如日志,事务等。
以下这段代码就是静态代码的实现示例:
public class StaticProxy {
interface Operator{
void op1();
void op2();
}
public static class A implements Operator{
public void op1() {
System.out.println("A execute op1");
}
public void op2() {
System.out.println("A execute op2");
}
}
public static class LogHandler implements Operator{
private Operator operator;
public LogHandler(Operator operator){
this.operator = operator;
}
public void op1() {
System.out.println("log before execute op1");
operator.op1();
System.out.println("log after execute op1");
}
public void op2() {
System.out.println("log before execute op2");
operator.op2();
System.out.println("log after execute op2");
}
}
public static void main(String[] args) {
Operator a = new A();
Operator logA = new LogHandler(a);
logA.op1();
logA.op2();
}
}
结果打印:
log before execute op1
A execute op1
log after execute op1
log before execute op2
A execute op2
log after execute op2
静态代理有什么问题?
1.不方便扩展修改,代码不易维护,以上例子同样是日志打印,在代理类中需要生成两个相同的方法,假设打印日志逻辑变更,需要修改所有的代理方法块
动态代理实现之JDK代理
JDK代理需要依赖于接口
代码实现如下所示
public class JdkProxy {
interface Operator {
void op1();
void op2();
}
interface Operator2 {
void op3();
}
public static class A implements Operator {
public void op1() {
System.out.println("A execute op1");
}
public void op2() {
System.out.println("A execute op2");
}
}
public static class B implements Operator2 {
public void op3() {
System.out.println("B execute op3");
}
}
public static class LogHandler implements InvocationHandler {
public Object object;
public LogHandler(Object object) {
this.object = object;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before execute");
Object invoke = method.invoke(object, args);
System.out.println("after execute");
return invoke;
}
}
public static void main(String[] args) {
A a = new A();
Operator logA = (Operator) Proxy.newProxyInstance(Operator.class.getClassLoader(), new Class[]{Operator.class}, new LogHandler(a));
logA.op1();
logA.op2();
B b = new B();
Operator2 logB = (Operator2) Proxy.newProxyInstance(Operator2.class.getClassLoader(), new Class[]{Operator2.class}, new LogHandler(b));
logB.op3();
}
}
结果打印:
before execute
A execute op1
after execute
before execute
A execute op2
after execute
before execute
B execute op3
after execute
动态代理的优点
以上案例说明,动态代理有用诸多优点
1.节省重复代码,相较于静态代理,日志打印代码逻辑只需要保持一份,并且更新之后所有代理对象都能影响
2.代理逻辑可以被多个接口复用
动态代理实现之Cglib代理
Cglib代理的原理是通过继承父类方法。
代码实现如下所示
public class CglibProxy {
public static class A {
public void op1() {
System.out.println("A execute op1");
}
public void op2() {
System.out.println("A execute op2");
}
}
public static class B {
public void op3() {
System.out.println("B execute op3");
}
}
public static class LogHandler implements MethodInterceptor {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before execute");
Object invoke = methodProxy.invokeSuper(o, objects);
System.out.println("after execute");
return invoke;
}
}
public static void main(String[] args) {
Enhancer enhancerA = new Enhancer();
enhancerA.setSuperclass(A.class);
enhancerA.setCallback(new LogHandler());
A a = (A) enhancerA.create();
a.op1();
a.op2();
Enhancer enhancerB = new Enhancer();
enhancerB.setSuperclass(B.class);
enhancerB.setCallback(new LogHandler());
B b = (B) enhancerB.create();
b.op3();
}
}
结果打印:
before execute
A execute op1
after execute
before execute
A execute op2
after execute
before execute
B execute op3
after execute
网友评论