Spring源码中的一段设计

来源:互联网 发布:国泰安数据服务中心 编辑:程序博客网 时间:2024/05/18 03:16

模式类型


        在Spring的源码里看到下面一段代码,使用方法感觉挺巧妙的,记录下来一下。

ReflectiveAspectJAdvisorFactory:

private List<Method> getAdvisorMethods(Class<?> aspectClass) {final List<Method> methods = new LinkedList<Method>();// 设计巧妙的地方正是这个地方:ReflectionUtils.MethodCallback()// 1,MethodCallback是一个类内部定义的接口,这样可以明确这个接口是为这个类服务的。// 2,当前类想得取符合自己想要的条件的对象,这些条件只有自己需要,所以在这里写条件的实现。//       当前类没有Method对象集合,把这些条件告诉有集合的对象:我把我的条件给你,请你把符合这些条件的对象给我。ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {@Overridepublic void doWith(Method method) throws IllegalArgumentException {// Exclude pointcutsif (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {methods.add(method);}}});Collections.sort(methods, METHOD_COMPARATOR);return methods;}

下面看一下ReflectionUtils.doWithMethods里面调用的doWithMethods方法的实现:
public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf) {// Keep backing up the inheritance hierarchy.Method[] methods = getDeclaredMethods(clazz);for (Method method : methods) {if (mf != null && !mf.matches(method)) {continue;}try {// 这个地方就是调用我们写的回调函数的地方// 这里持有Method集合mc.doWith(method);}catch (IllegalAccessException ex) {throw new IllegalStateException("Not allowed to access method '" + method.getName() + "': " + ex);}}if (clazz.getSuperclass() != null) {doWithMethods(clazz.getSuperclass(), mc, mf);}else if (clazz.isInterface()) {for (Class<?> superIfc : clazz.getInterfaces()) {doWithMethods(superIfc, mc, mf);}}}

模式的使用

    
        这样的模式使用在什么地方呢?感觉这个模式和模板模式有点像,把共同的处理集中起来,把特殊处理写成接口,让使用它的地方自己实现。实现接口的地方可以做自己想做的事,例如:
  • 定制条件,取得其它集合中符合条件数据
  • 执行我们要想做的处理
“执行我们想要做的处理”这个使用方法,曾经做过一次。使用Mybatis和Mysql的系统上,要做批量插入。DAO方法是用注解(@Insert)写的,例如:
    @(Insert "Insert Into XXX ......")
    void insertUserInfo(User user);

很多地方要这么写,于是写了一个抽象类,抽象类的作用:
  • 控制循环。例如:10000插入后次执行一次Batch
  • 暴露一个回调让使用者去实现,只要把自己要执行的DAO方法写里面就可以。

实现如下:
public abstract class AbstractBatchCommit<T> {    /**     * 执行每N条记录更新一次数据库     * @author shijiapeng     * @date 2016年9月22日     * @param list     */    public void commitBatch(List<T> list) {        try{            // 声明存储N条记录的List            List<T> commitList = new ArrayList<T>(Constants.BATCH_COMMIT_SIZE);            for(int idx = 0; idx < list.size(); idx++){                commitList.add(list.get(idx));                // 每N条数据执行更新一歆                 if(idx !=0 && (idx + 1)%Constants.BATCH_COMMIT_SIZE == 0){                    // 批量更新数据库                    callSQL(commitList);                    // 清空list                    commitList.clear();                }            }                        // 小于N条,或者N条以上的零头时,执行一次            if(!commitList.isEmpty()){                callSQL(commitList);            }                    } catch(Exception e){            e.printStackTrace();            throw new RuntimeException(e);        }    }        /*     * 调用SQL语句     */    public abstract void callSQL(List<T> list) throws SQLException;}







0 0
原创粉丝点击