动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实,并且可以对方法请求前后对参数或者结果进行处理。最重要就是解耦,在代理里操作对象完全跟实际对象解耦。
代理实现三步骤:
- 接口,接口中的方法是要真正去实现的
- 被代理类,实现上述接口,这是真正去执行接口中方法的类
- 代理类,实现InvocationHandler,帮助被代理类去实现方法
接口:
/**
* <P>File name : Subject.java </P>
* <P>Author : zhuxiaocheng </P>
* <P>Date : May 29, 2018 </P>
*/
public interface Subject {
public void doSomething(String name);
}
实现类:
public class RealSubject implements Subject {
/**
* <P>Author : zhuxiaocheng </P>
* <P>Date : May 29, 2018 </P>
* @see com.zhu.proxy.Subject#doSomething()
*/
@Override
public void doSomething(String name) {
System.out.println( "call doSomething():"+name );
throw new RuntimeException();
}
}
代理类:
/**
* <P>File name : ProxyHandler.java </P>
* <P>Author : zhuxiaocheng </P>
* <P>Date : May 29, 2018 </P>
*/
public class ProxyHandler implements InvocationHandler {
private Object tar;
//绑定委托对象,并返回代理类
public Object bind(Object tar)
{
this.tar = tar;
//绑定该类实现的所有接口,取得代理类
return Proxy.newProxyInstance(tar.getClass().getClassLoader(),
tar.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
//这里就可以进行所谓的AOP编程了
//在调用具体函数方法前,执行功能处理
try{
result = method.invoke(tar,args);
}catch (Exception e) {
System.out.println("回滚");
}
//在调用具体函数方法后,执行功能处理
return result;
}
}
测试:
public class TestProxy {
public static void main(String args[])
{
ProxyHandler proxy = new ProxyHandler();
//绑定该类实现的所有接口
Subject sub = (Subject) proxy.bind(new RealSubject());
sub.doSomething("朱小成");
}
}
结果:
call doSomething():朱小成
回滚