代理模式在Spring中的應用

代理模式在Spring中主要體現在Spring框架的核心功能之一的AOP,通過AOP將切面通知織入到指定的切點位置,簡單一點就是可以是現在某個方法運行前後添加指定的功能。下面簡單實現一個將攔截器織入指定的方法上。
1 攔截器接口

public interface Intercepter {
    boolean before();
    void after();
    Object around(Invocation invocation) throws InvocationTargetException, IllegalAccessException;
    void afterReturning();
    void afterThrowing();
    boolean userAround();
}

2 攔截器實現類

public class MyIntercepter implements Intercepter {
    @Override
    public boolean before() {
        System.out.println("before ===========");
        return true;
    }

    @Override
    public void after() {
        System.out.println("after ===========");
    }

    @Override
    public Object around(Invocation invocation) throws InvocationTargetException, IllegalAccessException {
        System.out.println("around before ============");
        Object obj = invocation.proceed();
        System.out.println("around after ============");
        return obj;
    }

    @Override
    public void afterReturning() {
        System.out.println("afterReturning ============");
    }

    @Override
    public void afterThrowing() {
        System.out.println("afterThrowing ============");
    }

    @Override
    public boolean userAround() {
        return true;
    }
}

3 自定義調用工具

public class Invocation {

    private Object[] params;

    private Object target;

    private Method method;

    public Invocation(Object[] params, Object target, Method method) {
        this.params = params;
        this.target = target;
        this.method = method;
    }

    public Object proceed() throws InvocationTargetException, IllegalAccessException {
        return method.invoke(target, params);
    }
}

4 自定義代理對象(類似Spring中的ProxyFactory生成代理類,將Interceptor織入)

public class ProxyBean implements InvocationHandler {

    private Object target;

    private Intercepter intercepter;

    public static Object getProxyBean(Object target, Intercepter intercepter) {
        ProxyBean proxyBean = new ProxyBean();
        proxyBean.target = target;
        proxyBean.intercepter = intercepter;
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), proxyBean);
        return proxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        boolean exceptionFlag = false;

        Invocation invocation = new Invocation(args, target, method);
        Object retObj = null;
        try {
            if(intercepter.before()) {
                retObj = intercepter.around(invocation);
            } else {
                retObj = method.invoke(target, args);
            }
        } catch (Exception e) {
            exceptionFlag = true;
        }

        intercepter.after();

        if(exceptionFlag) {
            intercepter.afterThrowing();
        } else {
            intercepter.afterReturning();
            return retObj;
        }
        return null;
    }
}

以上這個代理類類似

/**
	 *創建一個新的代理工廠,擁有需要代理的接口和織入的攔截器
	 */
	public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
		addInterface(proxyInterface);
		addAdvice(interceptor);
	}
public Object getProxy() {
		return createAopProxy().getProxy();
	}

調用代理類間接調用接口方法,就能實現在指定方法前後織入相應的攔截器功能。關於Spring AOP功能的具體實現後面再分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章