日期:2014-05-17  浏览次数:20714 次

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

从代理机制初探AOP
如想在执行HelloSpeaker的hello()方法时留下日志消息,可以在hello()方法内部写log,或者说将执行log的程序横切入(Cross-cutting)到HelloSpeaker,但这样就使得HelloSpeaker关注了不属于它自己的业务逻辑。如是可以采取代理的机制(代理模式)
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 

代理(Proxy)有两种:
静态代理-Static proxy
动态代理-Dynamic proxy

1. 静态代理
为实现静态代理需要为HelloSpeaker写一个HelloProxy类,同样实现IHello接口,并在hello方法执行log,并执行HelloSpeaker的hello()方法。
Java code

/**
 * 此处可以为接口也可以为抽象类
 * @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();
    }
}



2:动态代理
Java code

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();
    }





------解决方案--------------------
先马后看
------解决方案--------------------
技术分享帖子 前面可以加上分享,大家就知道了
探讨

引用:

先马后看


好奇怪 我发的帖子都木有人看, 是不是人品问题?