欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

用JDK DyProxy 模拟 AOP 实现

程序员文章站 2022-04-13 09:17:17
...

package test;import java.lang.reflect.*;/** * Created with IntelliJ IDEA. * User: e513480 * Date: 12/3/13 * Time: 4:39 PM * To change this template use File | Settings | File Templates. */interface SomeInterface { public String someMethod(

 
package test;
import java.lang.reflect.*;
/**
 * Created with IntelliJ IDEA.
 * User: e513480
 * Date: 12/3/13
 * Time: 4:39 PM
 * To change this template use File | Settings | File Templates.
 */
interface SomeInterface {
    public String someMethod(String val);
}
class SomeBean implements SomeInterface {
    @Override
    public String someMethod(String val) {
        System.out.println("some method invoked, val=" + val);
        if ("throw1".equalsIgnoreCase(val)) {
            throw new IllegalArgumentException("This is a Exception");
        } else if ("throw2".equalsIgnoreCase(val)) {
            throw new IllegalStateException("This is a Exception");
        }
        return val;
    }
}
class InvocationHandlerAdapter implements InvocationHandler {
    private Object proxyedObject;
    private Advice advice;
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object ret = null;
        try {
            advice.doBeforeInvoke(proxyedObject, method, args);
            ret = method.invoke(proxyedObject, args);
            advice.doAfterSuccessInvoke(proxyedObject, method, args);
        } catch (InvocationTargetException e) {
            advice.doAfterThrows(proxyedObject, method, args, e.getCause());
        } finally {
            advice.doAfterInvoke(proxyedObject, method, args);
        }
        return ret;
    }
    public Object getProxyedObject() {
        return proxyedObject;
    }
    public void setProxyedObject(Object proxyedObject) {
        this.proxyedObject = proxyedObject;
    }
    public Advice getAdvice() {
        return advice;
    }
    public void setAdvice(Advice advice) {
        this.advice = advice;
    }
}
interface Advice {
    void doBeforeInvoke(Object proxyedObject, Method method, Object[] args);
    void doAfterSuccessInvoke(Object proxyedObject, Method method, Object[] args);
    void doAfterInvoke(Object proxyedObject, Method method, Object[] args);
    void doAfterThrows(Object proxyedObject, Method method, Object[] args, Throwable e) throws Throwable;
}
public class ProxyTest {
    private static  T createProxy(String beanName, Advice advice) {
        T proxy = null;
        try {
            InvocationHandlerAdapter handler = new InvocationHandlerAdapter();
            handler.setAdvice(advice);
            Class toBeProxedClass = Class.forName(beanName);
            handler.setProxyedObject(toBeProxedClass.newInstance());
            proxy = (T) Proxy.newProxyInstance(toBeProxedClass.getClassLoader(), toBeProxedClass.getInterfaces(), handler);
        } catch (Exception e) {
            throw new IllegalArgumentException("Failed to create proxy.", e);
        }
        return proxy;
    }
    public static void main(String[] args) {
        try {
            String beanName = "test.SomeBean";
            Advice advice = new Advice() {
                @Override
                public void doBeforeInvoke(Object proxyedObject, Method method, Object[] args) {
                    System.out.println("doBeforeInvoke");
                }
                @Override
                public void doAfterSuccessInvoke(Object proxyedObject, Method method, Object[] args) {
                    System.out.println("doAfterSuccessInvoke");
                }
                @Override
                public void doAfterInvoke(Object proxyedObject, Method method, Object[] args) {
                    System.out.println("doAfterInvoke");
                }
                @Override
                public void doAfterThrows(Object proxyedObject, Method method, Object[] args, Throwable e) throws Throwable {
                    System.out.println("doAfterThrows, the exception is " + e);
                    if (e instanceof IllegalStateException) {
                        //throw2
                        throw e;
                    }
                }
            };
            SomeInterface proxy = createProxy(beanName, advice);
            System.out.println("------------begin---------------------");
            String val = proxy.someMethod("hello");
            System.out.println("returned val=" + val);
            System.out.println("------------end---------------------");
            System.out.println("------------begin---------------------");
            val = proxy.someMethod("throw1");
            System.out.println("returned val=" + val);
            System.out.println("------------end---------------------");
            System.out.println("------------begin---------------------");
            try {
                val = proxy.someMethod("throw2");
                System.out.println("should not get to here");
            } catch (IllegalStateException e) {
                System.out.println("should get to here");
            }
            System.out.println("returned val=" + val);
            System.out.println("------------end---------------------");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}