代理模式:就是为了分离出业务层而采取的一种模式,比如说在一个逻辑中,要记录逻辑执行前后的日志,那么通常我们的方法是这样的
方法名
(){
记录日志
逻辑代码
记录日志
}
当逻辑代码和日志代码写到一起的时候,我们就会发现这个方法中包含了太多的东西,显得有些混乱,解决这种情况我们可以采取代理模式。
静态代理模式:
采取静态代理模式我们需要一个公共接口,同过实现此接口来生成代理类和业务类
比如:
package
staticProxy;
/**
*
接口
*
@author
David.Qiu
*
*/
public
interface
IOperate {
public
void
doExcute();
}
在这个接口中,我们有一个doExcute方法,这个方法将在继承此接口的类中执行业务逻辑
下面我们生成一个业务类
package staticProxy;
/**
* 真实角色
* @author David.Qiu
*
*/
public class RealOperate implements IOperate {
public RealOperate() {
// TODO Auto-generated constructor stub
}
public void doExcute() {
// TODO Auto-generated method stub
System.out.println("Real Class is doing something!");
}
}
在这个类中,我们实现了接口中的方法,并且只让他执行业务,打印出字符串。
之后我们需要生成一个代理类来代理执行业务逻辑
package staticProxy;
/**
* 代理角色
* @author David.Qiu
*
*/
public class ProxyOperate implements IOperate {
//private RealOperate realOperate;
private IOperate realOperate;
public ProxyOperate(IOperate realOperate) {
// TODO Auto-generated constructor stub
this.realOperate=realOperate;
}
public void doExcute() {
// TODO Auto-generated method stub
start();
/**
if(realOperate==null){
realOperate=new RealOperate();
}
*/
realOperate.doExcute();
end();
}
/**
* start
*/
public void start(){
System.out.println("start...");
}
/**
* end
*/
public void end(){
System.out.println("end...");
}
}
在这个代理类中,我们照样实现了接口中的方法,只不过在这一次我们在方法中加入了日志记录操作,并且通过调用业务类来实现业务逻辑,这样,我们就可以把业务逻辑和日志记录分开了。
当我们的业务逻辑改变时,只需要修改
RealOperate中的doExcute方法就可以了,这样可以让程序看起来耦合度比较低。
测试一下:
package staticProxy;
/**
* 测试类
* @author David.Qiu
*
*/
public class TestMain {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
IOperate proxyOperate=new ProxyOperate(new RealOperate());
proxyOperate.doExcute();
}
}
当然,上面所说的是静态代理方法,只是个代理模式的原理,如果真正使用的话我们最好使用动态代理,所以下面我们来看一下动态代理
动态代理:
当然,接口还是需要的
package
dynamicProxy;
public
interface
IOperate {
public
void
doExecute();
}
生成业务类
package dynamicProxy;
public class RealOperate implements IOperate {
public void doExecute() {
// TODO Auto-generated method stub
System.out.println("Real Class is doing something!");
}
}
重点我们看下代理类,它需要实现一个接口
java.lang.reflect.InvocationHandler
,该接口中有个方法Object invoke(Object proxy, Method method,Object[] args)
throws
Throwable
package
dynamicProxy;
import
java.lang.reflect.InvocationHandler;
import
java.lang.reflect.Method;
import
java.lang.reflect.Proxy;
public
class
ProxyOperate
implements
InvocationHandler {
private
Object
object
;
public
Object bind(Object object){
this
.
object
=object;
return
Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),
this
);
}
public
Object invoke(Object proxy, Method method, Object[] args)
throws
Throwable {
//
TODO
Auto-generated method stub
System.
out
.println(
"Start..."
);
method.invoke(
this
.
object
,
null
);
System.
out
.println(
"End..."
);
return
null
;
}
}
测试一下
package
dynamicProxy;
public
class
TestMain {
/**
*
@param
args
*/
public
static
void
main(String[] args) {
//
TODO
Auto-generated method stub
ProxyOperate proxy=
new
ProxyOperate();
IOperate operate=(IOperate) proxy.bind(
new
RealOperate());
operate.doExecute();
}
}
从这两个例子中可以看出代理模式在保持系统的低耦合方面是个不错的选择,
Spring框架中的AOP就是根据代理模式得来的,AOP的一些东西我将会在下一片文章中介绍。