本文将通过比较JAVA静态代理和动态代理的区别,来分析动态代理的优点。代理模式和动态代理的概念请百度或者Google,本文不细叙。
功能:我们有使用一个实际的类RealSubject,并且还能统计这个类里所有方法的运行时间,这个时候就可以通过动态代理来实现了。
1. 定义一个共同接口Subject
public interface Subject {
public void doSomething();
public void doOthers();
//public void verify();
}
2. 定义一个需要被代理的实际的类并实现Subject接口
public class RealSubject implements Subject{
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("call doSomething()");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void doOthers() {
// TODO Auto-generated method stub
System.out.println("call doOthers()");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void verify() {
// TODO Auto-generated method stub
System.out.println("call verify()");
for(int i=0;i<10000000;i++){
System.out.print("");
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3.. 定义一个静态代理类StaticProxy
public class StaticProxy implements Subject {
private RealSubject realRealSubject;
public StaticProxy(RealSubject realRealSubject) {
super();
this.realRealSubject = realRealSubject;
}
@Override
public void doSomething() {
// TODO Auto-generated method stub
System.out.println("static do sth before.");
realRealSubject.doSomething();
System.out.println("static do sth afterward.");
}
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Subject subject = new StaticProxy(realSubject);
subject.doSomething();
subject.doOthers();
}
@Override
public void doOthers() {
// TODO Auto-generated method stub
System.out.println("static do sth before.");
System.out.println("call doOthers()");
System.out.println("static do sth afterward.");
}
@Override
public void verify() {
// TODO Auto-generated method stub
}
}
//可以看出,静态代理类需要实现Subject接口的所有方法,但Subject接口增加或者删除其中某个方法时,静态代理类需要跟着修改。
4. 定义一个动态代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.xml.stream.events.StartDocument;
public class DynamicProxy implements InvocationHandler {
private Object object;
public DynamicProxy() {
}
public Object bindObject(Object object){
this.object = object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("do sth before.");
long start = System.currentTimeMillis();
Object result = method.invoke(object, args);
long end = System.currentTimeMillis();
System.out.println("do sth afterward.");
System.out.println("call method "+method.getName()+" last for "+(end-start));
System.out.println();
return result;
}
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Subject proxySubject = (Subject) new DynamicProxy().bindObject(realSubject);
proxySubject.doSomething();
proxySubject.doOthers();
proxySubject.verify();
}
}
输出结果
do sth before.
call doSomething()
do sth afterward.
call method doSomething last for 10
do sth before.
call doOthers()
do sth afterward.
call method doOthers last for 10
do sth before.
call verify()
do sth afterward.
call method verify last for 1176
由此可见,使用动态代理类可以在被代理类的每个方法前后增加功能,这也是Spring AOP面向切面编程的一个重要思想。在动态代理的实现中,我们用到了Java的反射机制,包括java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类。
本文是自己学习的一个总结,欢迎交流指正。

本文通过对比JAVA静态代理和动态代理,介绍了动态代理的优势及其应用场景。文章详细解释了如何利用动态代理实现在目标方法调用前后增加功能,展示了具体的代码实现过程。
168万+

被折叠的 条评论
为什么被折叠?



