代理模式 与 Spring AOP

AOP:在一个服务的流程中插入与业务逻辑无关的系统服务逻辑(例如Logging、Security),这样的逻辑称为Cross-cutting concerns,将Cross-cutting concerns独立出来设计为一个对象,这样的特殊对象称之为Aspect,Aspect-oriented programming着重在Aspect的设计上以及与应用程序的织入(Weave)。

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

代理模式的UML图:

RealSubject类 和 Proxy类 都实现 Subject接口,并且Proxy类中保持RealSubject的依赖。 

 

从java的角度考虑,代理(Proxy)可以分为两种:

静态代理-Static proxy

动态代理-Dynamic proxy

 

静态代理例子:

/**
 * 此处可以为接口也可以为抽象类
 * @author ljn
 *
 */
public interface IHelloSpeaker {
    public abstract void hello();
}
 
/**
 * 接口实现类日志功能  简单的打印一句话
 * @author ljn
 *
 */
public class HelloSpeaker implements IHelloSpeaker {
    public void hello(){
        System.out.println("............this is Log");
    }
}
 
/**
 * 代理类实现IHelloSpeaker接口,同时拥有实际对象的引用(private HelloSpeaker helloObj;//代理类内部引用真实类)
 * 代理必须完成委托对象的动作,也可以添加自己的动作(doBefore,doAfter)。
 *
 * @author ljn
 *
 */
public class HelloProxy implements IHelloSpeaker {
 
    private HelloSpeaker helloObj;// 代理类内部引用委托类
 
    public HelloProxy(HelloSpeaker helloSpeaker) {
        this.helloObj = helloSpeaker;
    }
 
    private void doBefore() {
        System.out.println("method doBefore invoke!");
    }
 
    private void doAfter() {
        System.out.println("method doAfter invoke!");
 
    }
 
    @Override
    public void hello() {
        // TODO Auto-generated method stub
        doBefore();// 其他业务逻辑
        helloObj = new HelloSpeaker();
        helloObj.hello();// 委托类具体的业务逻辑。
        doAfter();// 其他业务逻辑
    }
}
/**
*测试类
*/
public class Test {
    public static void main(String[] args) {
//其中HelloProxy中helloObject为需要代理的对象,在其它地方如下来使用代理机制
        IHelloSpeaker proxy = new HelloProxy(new HelloSpeaker());
        proxy.hello();
    }
}

 

动态代理例子:

 

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
public class LogHandler implements InvocationHandler {
 
    private Object delegate;
 
    public Object bind(Object delegate) {
        this.delegate = delegate;
        return Proxy.newProxyInstance(
                           delegate.getClass().getClassLoader(),
                           delegate.getClass().getInterfaces(),
                           this);
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        Object result = null;
        try {
            System.out.println("method starts..."+method);
            result = method.invoke(delegate, args);
            System.out.println("method starts..."+method);
        } catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }
}
//测试程序
public static void main(String[] args) {
        LogHandler logHandler  = new LogHandler();
 
        IHelloSpeaker helloProxy =
                (IHelloSpeaker) logHandler.bind(new HelloSpeaker());
        helloProxy.hello();
    }

 

参考:

http://www.blogjava.net/DoubleJ/archive/2008/03/04/183796.html

http://greemranqq.iteye.com/blog/1815096

http://bbs.csdn.net/topics/390199476

代理模式 与 Spring AOP,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。