模式类型
在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() {
@Override
public void doWith(Method method) throws IllegalArgumentException {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}
});
Collections.sort(methods, METHOD_COMPARATOR);
return methods;
}
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);
}
}
}
模式的使用
这样的模式使用在什么地方呢?感觉这个模式和模板模式有点像,把共同的处理集中起来,把特殊处理写成接口,让使用它的地方自己实现。实现接口的地方可以做自己想做的事,例如:
@(Insert "Insert Into XXX ......")
void insertUserInfo(User user);
- 定制条件,取得其它集合中符合条件数据
- 执行我们要想做的处理
@(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;
}