文档章节

JavaAop动态代理工具类

思想永无止境
 思想永无止境
发布于 2016/11/04 11:57
字数 804
阅读 26
收藏 0
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/** * Aop动态代理工具类 * * @author tang * */
public class AopUtils {

    /*----------------------------begin test AopUtils------------------------------*/
    public static interface I1 {
        void i1();
    }

    public static interface I2 {
        void i2();
    }

    public static interface I3 {
        void i3();
    }

    public static interface T1 {
        void t1();
    }

    public static interface TX {
        void tx();
    }

    public static class A implements I1, I2, I3, T1, TX {
        public void i1() {
            System.out.println(I1.class.getSimpleName());
        }

        public void i2() {
            System.out.println(I2.class.getSimpleName());
        }

        public void i3() {
            System.out.println(I3.class.getSimpleName());
        }

        public void t1() {
            System.out.println(T1.class.getSimpleName());
        }

        public void tx() {
            System.out.println(TX.class.getSimpleName());
        }
    }

    public static void main(String[] args) {

        AopAdapter aopAdapter = new AopAdapter() {
            @Override
            public void before(Object proxy, Method method, Object[] args) {
                System.out.println("before...");
            }

            @Override
            public void after(Object proxy, Method method, Object[] args) {
                System.out.println("after...");
            }

            @Override
            public void excep(Object proxy, Method method, Object[] args) {
                System.out.println("excep...");
            }
        };

        String[] includeRegexs = { "i*"// 字母"i"开头的方法需要执行AOP
                , "\\w\\d" // 方法名第一个字符是字母第二个字符是数字需要执行AOP
        };
        String[] excludeRegexs = { "*2"// 2结尾的方法不需要执行AOP
        };
        // excludeRegexs的优先级高于includeRegexs

        Object proxy = getProxy(new A(), aopAdapter, aopAdapter, aopAdapter, includeRegexs, excludeRegexs, false);

        System.out.println("----------");
        ((I1) proxy).i1();
        System.out.println("----------");
        ((I2) proxy).i2();
        System.out.println("----------");
        ((I3) proxy).i3();
        System.out.println("----------");
        ((T1) proxy).t1();
        System.out.println("----------");
        ((TX) proxy).tx();
        System.out.println("----------");
    }

    /*----------------------------end test AopUtils------------------------------*/

    public static interface CallBefore {
        void before(Object proxy, Method method, Object[] args);
    }

    public static interface CallAfter {
        void after(Object proxy, Method method, Object[] args);
    }

    public static interface ExcepCatch {
        void excep(Object proxy, Method method, Object[] args);
    }

    public static abstract class AopAdapter implements CallBefore, CallAfter, ExcepCatch {

        @Override
        public void excep(Object proxy, Method method, Object[] args) {
        }

        @Override
        public void after(Object proxy, Method method, Object[] args) {
        }

        @Override
        public void before(Object proxy, Method method, Object[] args) {
        }
    }

    private static boolean exist(Method method, String[] methodNames) {

        if (methodNames == null || methodNames.length == 0) {
            return false;
        }
        for (int i = 0; i < methodNames.length; i++) {
            if (method.getName().equals(methodNames[i])) {
                return true;
            }
            int indexOf = methodNames[i].indexOf('*');
            if (indexOf == 0) {
                String back = methodNames[i].substring(indexOf + 1);
                if (method.getName().endsWith(back)) {
                    return true;
                }
            } else if (indexOf == methodNames[i].length() - 1) {
                String front = methodNames[i].substring(0, indexOf);
                if (method.getName().startsWith(front)) {
                    return true;
                }
            } else {
                if (method.getName().matches(methodNames[i])) {
                    return true;
                }
            }
        }

        return false;
    }

    public static Object getProxy(Object object, AopAdapter aopAdapter, String[] includeRegexs) {
        return getProxy(object, aopAdapter, aopAdapter, aopAdapter, includeRegexs, null, false);
    }

    public static Object getProxy(Object object, AopAdapter aopAdapter, String[] includeRegexs, String[] excludeRegexs) {
        return getProxy(object, aopAdapter, aopAdapter, aopAdapter, includeRegexs, excludeRegexs, false);
    }

    public static Object getProxy(Object object, AopAdapter aopAdapter, String[] includeRegexs, String[] excludeRegexs, boolean isIgroreExcep) {
        return getProxy(object, aopAdapter, aopAdapter, aopAdapter, includeRegexs, excludeRegexs, isIgroreExcep);
    }

    /** * excludeRegexs的优先级高于includeRegexs * * @param object * 被代理对象 * @param before * 方法调用之前需要的切入的代码 * @param after * 方法调用之前需要的切入的代码 * @param excep * 方法捕获异常时需要的切入的代码 * @param includeRegexs * 哪些方法需要AOP * @param excludeRegexs * 哪些方法不需要AOP * @param isIgroreExcep * 是否忽略异常 * @return 实现被代理对象所有接口的代理对象,并在实现的接口方法内切入了一定的代码 */
    public static Object getProxy(final Object object, final CallBefore before, final CallAfter after, final ExcepCatch excep, final String[] includeRegexs,
            final String[] excludeRegexs, final boolean isIgroreExcep) {

        if (object == null) {
            throw new RuntimeException("object is null");
        }
        if (object.getClass().getInterfaces().length < 1) {
            throw new RuntimeException("object is not have implement any interface");
        }
        if (before == null && after == null && excep == null) {
            throw new RuntimeException("parameter all is empty");
        }

        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                boolean isEmptyIncludeRegexs = includeRegexs == null || includeRegexs.length == 0;
                boolean isEmptyExcludeRegexs = excludeRegexs == null || excludeRegexs.length == 0;

                boolean isExecuteAop = false;
                if (!isEmptyIncludeRegexs && !isEmptyExcludeRegexs) {
                    isExecuteAop = exist(method, includeRegexs) && !exist(method, excludeRegexs);
                } else if (isEmptyIncludeRegexs && isEmptyExcludeRegexs) {
                    isExecuteAop = false;
                } else if (isEmptyIncludeRegexs) {
                    isExecuteAop = !exist(method, excludeRegexs);
                } else if (isEmptyExcludeRegexs) {
                    isExecuteAop = exist(method, includeRegexs);
                }
                boolean isExecuteBefore = isExecuteAop && before != null;
                boolean isExecuteAfter = isExecuteAop && after != null;
                boolean isExecuteExcep = isExecuteAop && excep != null;

                if (isExecuteBefore) {
                    before.before(proxy, method, args);// 切入代码
                }

                Object result = null;
                try {
                    result = method.invoke(object, args);
                } catch (Exception e) {
                    if (isExecuteExcep) {
                        excep.excep(proxy, method, args);// 切入代码
                    }
                    if (isIgroreExcep) {
                        e.printStackTrace();
                    } else {
                        throw e;
                    }
                }

                if (isExecuteAfter) {
                    after.after(proxy, method, args);// 切入代码
                }

                return result;
            }
        });
    }
}

如上代码执行所打印的结果为:

---------- before... I1 after... ----------
I2 ----------
before...
I3
after... ----------
before...
T1
after... ----------
TX ----------

© 著作权归作者所有

思想永无止境
粉丝 4
博文 257
码字总数 292814
作品 0
昌平
程序员
私信 提问
SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架

1 JDK动态代理详解   静态代理、JDK动态代理、Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文。   1.1 JDK代理的基本步骤     》通过实现InvocationHandler接口来自定义自...

CRUD_Architect
2018/08/23
0
0
JDK动态代理源码学习

继上一篇博客设计模式之代理模式学习之后http://blog.csdn.net/u014427391/article/details/75115928,本博客介绍JDK动态代理的实现原理,学习一下JDK动态代理的源码。 Proxy类。该类即为动态...

Javahih
2017/07/21
0
0
Castle Windsor 的动态代理类如何获取实际类型

问题 在实际开发过程当中我们可能会针对某些类型使用动态代理技术(AOP),注入了一些拦截器进行处理,但是一旦某个类型被动态代理了,那么就会生成一个代理类。这个时候在该类内部使用 方法获...

myzony
03/07
0
0
静态代理与静态代理

1 代理模式及概念 代理模式是给某个对象提供一个代理对象,并由代理对象控制对原始对象的引用。如下图: 代理类和委托类有共同的父类,这样在任何使用原始对象(委托对象)的地方都可用代理对...

林中漫步
2016/05/15
80
0
静态代理与动态代理实现与原理

基础代码准备 接口类: public interface IUser { /** * 判断用户的权限 * @param uid 用户的UID * @return / public boolean isAuthUser(int uid);} 实现类: /* * 类的实现 * @author Jaso......

ifree613
2016/03/11
892
0

没有更多内容

加载失败,请刷新页面

加载更多

Jenkins系列_插件安装及报错处理

进入Jenkins之后我们可以进行插件的安装,插件管理位于以下模块: 发现上面报了一堆错误,是因为插件的依赖没有安装好,那么这一节,就先把这些错误解决掉吧。解决完成后,也就基本会使用插件...

shzwork
今天
2
0
mysql mysql的所有查询语句和聚合函数(整理一下,忘记了可以随时看看)

查询所有字段 select * from 表名; 查询自定字段 select 字段名 from 表名; 查询指定数据 select * from 表名 where 条件; 带关键字IN的查询 select * from 表名 where 条件 [not] in(元素...

edison_kwok
昨天
9
0
解决多线程并行加载缓存问题(利用guava实现)

依赖 com.google.guava:guava:20.0 import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import java.util.concurrent.ExecutionException;import j......

暗中观察
昨天
3
0
利用VisualVM 内存查看

准备工作,建几个测试类。等下就是要查看这几个类里面的属性 package visualvm;public class MultiObject { private String str; private int i; MultiObject(String str...

冷基
昨天
3
0
组装一台工作游戏两用机

一、配置清单如下: 分类 项目 价格(元) 主板 华硕(ASUS)TUF Z370-PLUS GAMING II 电竞特工 Z370二代 支持9代CPU 1049 CPU 英特尔(Intel) i7 8700K 酷睿六核 盒装CPU处理器 2640 风扇 九...

mbzhong
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部