改写的Spring监听器,拦截器,myBatis拦截器

   为方便使用,对Spring监听器,拦截器,myBatis拦截器做了一些简单的简化处理。如图:

一、Spring拦截器:

public class CommonMVCInterceptor implements HandlerInterceptor {

	@Autowired(required = false)
	List<EasyMvcInterceptor> interceptors;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		return doPreHandle(request, response, handler);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
		// 简单处理下后面的逻辑,用处不大
		doAfterInterceptor();
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		// 简单处理下后面的逻辑,用处不大
		doAfterInterceptor();
	}

	private boolean doPreHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
		if (!neet2Interceptor(handler)) {
			return true;
		}
		for (EasyMvcInterceptor interceptor : interceptors) {
			boolean excuteSuccess = interceptor.doBusiness((HandlerMethod) handler, request, response);
			if (!excuteSuccess) {
				return false;
			}
		}
		return true;
	}

	private void doAfterInterceptor() {
		if (null != interceptors && interceptors.size() > 0) {
			for (EasyMvcInterceptor interceptor : interceptors) {
				interceptor.doAfterInterceptor();
			}
		}
	}

	private boolean neet2Interceptor(Object handler) {
		return handler instanceof HandlerMethod && null != interceptors && interceptors.size() > 0;
	}

}
public interface EasyMvcInterceptor {

	default void doAfterInterceptor() {

	}

	default boolean doBusiness(HandlerMethod handlerMethod, HttpServletRequest request, HttpServletResponse response) {
		return doBusiness(handlerMethod, request);
	}

	default boolean doBusiness(HandlerMethod handlerMethod, HttpServletRequest request) {
		Method method = handlerMethod.getMethod();
		return doBusiness(method, request);
	}

	default boolean doBusiness(Method method, HttpServletRequest request) {
		return doBusiness(method, SystemUtils.getRequestParams(request));
	}

	default boolean doBusiness(Method method, Map<String, String> params) {
		return true;
	}

}

//配置类
@Configuration
public class WebConfig implements WebMvcConfigurer {

	@Bean
	public CommonMVCInterceptor commonMVCInterceptor() {
		return new CommonMVCInterceptor();
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		// 限流拦截
		InterceptorRegistration commonMVCInterceptor= registry.addInterceptor(commonMVCInterceptor());
		commonMVCInterceptor.addPathPatterns("/**");
		commonMVCInterceptor.excludePathPatterns( "/error/**", "uedit");
		commonMVCInterceptor.order(1);
	}
	}
//限流拦截器
public class LimitInterceptor implements EasyMvcInterceptor {

	@Override
	public boolean doBusiness(Method method, HttpServletRequest request) {
		Limiter limiter = method.getAnnotation(Limiter.class);
		if (null != limiter) {
			try {
				String api = SystemUtils.getApiFromRequest(request);
				String token = RedisRaterLimiter.acquireTokenFromBucket(api,limiter.limit(), limiter.timeout());
				if (null == token) {
					throw new LocalException("您的访问太过频繁");
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new LocalException("您的访问太过频繁");
			}
		}
		return true;
	}
}

好处:
1、Spring拦截器只用注册一次,
2、不用再去作HandlerMethod 类型转换类型判断。
3、方便扩展。

二、Spring容器刷新监听器

public class CommonSpringListener implements ApplicationListener<ContextRefreshedEvent> {

	@Autowired(required = false)
	List<EasySpringListener> easySpringListeners;

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {

		ApplicationContext applicationContext = event.getApplicationContext();
		// 异步执行一些容器启动时的初始化工作
		if (null != easySpringListeners && easySpringListeners.size() > 0) {
			easySpringListeners.forEach((easySpringListener) -> {
				easySpringListener.doSome(applicationContext);
			});
		}
	}
}
public interface EasySpringListener {
	public void doSome(ApplicationContext applicationContext);
}

使用示例,

public class DictUtils implements EasySpringListener {
	@Override
	public void doSome(ApplicationContext applicationContext) {
		initDictionary();
	}

对监听器只做了些简单的处理,不用每次去获取容器

三、MyBatis拦截器

@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
@Component
@Slf4j
public class CommonSqlInterceptor implements Interceptor {

	@Autowired
	List<EasySqlInterceptor> interceptors;

	@Override
	public Object intercept(Invocation invocation) throws Throwable {

		Object state = invocation.getArgs()[0];
		Object paremModel = invocation.getArgs()[1];
		if (!need2Interceptor(state ,paremModel )) {
			return invocation.proceed();
		}

		MappedStatement ms = (MappedStatement) state;
		// 处理执行前的逻辑
		executorBeforeExecutor(ms, paremModel);
		// 执行sql
		Object proceed = invocation.proceed();
		// 处理执行后的逻辑
		executorAfterExecutor(ms, paremModel);
		
		return proceed;
	}

	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties properties) {

	}

	private void executorBeforeExecutor(MappedStatement ms, Object paremModel) {
		if (null != interceptors && interceptors.size() > 0) {
			try {
				interceptors.forEach(it -> it.doBusinessBeforeExecutor(ms, paremModel));
			} catch (Exception e) {
				// 不影响正常逻辑的使用
				return;
			}
		}
	}

	private void executorAfterExecutor(MappedStatement ms, Object paremModel) {
		if (null != interceptors && interceptors.size() > 0) {
			try {
				interceptors.forEach(it -> it.doBusinessAfterExecutor(ms, paremModel));
			} catch (Exception e) {
				// 不影响正常逻辑的使用
				log.warn("处理sql执行后逻辑出错,错误类型={},错误消息={}", e.getClass(), e.getMessage());
				return;
			}
		}
	}

	//只拦截对象,不拦截集合等参数
	private boolean need2Interceptor(Object state, Object paremModel) {
		boolean isMappedStatement = state instanceof MappedStatement;
		if (!isMappedStatement) {
			return false;
		}
		if (null == paremModel) {
			return false;
		}
		boolean isMap = paremModel instanceof Map;
		if (isMap) {
			return false;
		}

		boolean isList = paremModel instanceof List;
		if (isList) {
			return false;
		}

		return true;
	}
}
public interface EasySqlInterceptor {

	default boolean condition() {
		return true;
	}

	default boolean condition(String sqlId) {
		return condition();
	}

	default boolean condition(MappedStatement ms, Object paremModel) {
		return condition(ms.getId());
	}

	default void doBusinessBeforeExecutor(MappedStatement ms, Object paremModel) {
		if (!condition(ms, paremModel)) {
			return;
		}
		String msId = ms.getId();
		if (isInsert(ms)) {
			doBusinessBeforeInsert(msId, paremModel);
		} else if (isUpdate(ms, paremModel)) {
			doBusinessBeforeUpdate(msId, paremModel);
		} else if (isDelete(ms, paremModel)) {
			doBusinessBeforeDelete(msId, paremModel);
		}
	}

	default void doBusinessBeforeInsert(String sqlId, Object paremModel) {

	}

	default void doBusinessBeforeUpdate(String sqlId, Object paremModel) {

	}

	default void doBusinessBeforeDelete(String sqlId, Object paremModel) {

	}

	// ------------------------------------------------------------------------------------------------------

	default void doBusinessAfterExecutor(MappedStatement ms, Object paremModel) {
		if (!condition()) {
			return;
		}
		String msId = ms.getId();
		if (isInsert(ms)) {
			doBusinessAfterInsert(msId, paremModel);
		} else if (isUpdate(ms, paremModel)) {
			doBusinessAfterUpdate(msId, paremModel);
		} else if (isDelete(ms, paremModel)) {
			doBusinessAfterDelete(msId, paremModel);
		}
	}

	default void doBusinessAfterInsert(String sqlId, Object paremModel) {

	}

	default void doBusinessAfterUpdate(String sqlId, Object paremModel) {

	}

	default void doBusinessAfterDelete(String sqlId, Object paremModel) {

	}

	public static boolean isInsert(MappedStatement ms) {
		return ms.getSqlCommandType().equals(SqlCommandType.INSERT);
	}

	public static boolean isUpdate(MappedStatement ms, Object paremModel) {
		return ms.getSqlCommandType().equals(SqlCommandType.UPDATE) && !isDelete(ms, paremModel);
	}

	public static boolean isDelete(MappedStatement ms, Object paremModel) {
		// 是直接删除
		boolean isDelete = ms.getSqlCommandType().equals(SqlCommandType.DELETE);
		if (isDelete) {
			return true;
		}
		// 是软删除
		List<String> deleteFlag = Arrays.asList("delete", "softDelete");
		boolean isSoftDelete = deleteFlag.stream().anyMatch(d -> ms.getId().indexOf(d) != -1);
		if (isSoftDelete) {
			return true;
		}
		// 是更新删除标误解
		Object fieldValue = DrinReflectUtils.getFieldValue(paremModel, "delFlag");
		return "1".equals(String.valueOf(fieldValue));
	}
}

使用示例:

public interface PublicFieldHandler extends EasySqlInterceptor {

	public String getFieldName();

	public Object getDefaultValue(String type);

	@Override
	default void doBusinessBeforeInsert(String msId, Object paremModel) {
		setValue(paremModel);
	}

	@Override
	default void doBusinessBeforeUpdate(String msId, Object paremModel) {
		setValue(paremModel, "updateBy", "updateDate");
	}

	default void setValue(Object object, String... names) {
		for (String name : names) {
			if (name.equals(getFieldName())) {
				setValue(object);
				break;
			}
		}
	}

	default void setValue(Object object) {
		try {
			Field field = object.getClass().getDeclaredField(getFieldName());
			if (null == field) {
				return;
			}
			field.setAccessible(true);
			// 看下原来是否设置了值
			Object oldValue = field.get(object);
			if (isNotNull(oldValue)) {
				return;
			}
			field.set(object, getDefaultValue(field.getType().getSimpleName()));
		} catch (Exception e) {
		}
	}

}
public class UpdateDateFieldHandler implements PublicFieldHandler {

	@Override
	public String getFieldName() {
		return “updateDate”;
	}

	@Override
	public Object getDefaultValue(String type) {
		FieldType valueOf = FieldType.valueOf(type);
		switch (valueOf) {
		case Long:
			return System.currentTimeMillis();
		default:
			return new Date();
		}
	}
}

你可能感兴趣的:(拦截器监听器,spring,java,后端)