• SpringAOP实战应用


    Springboot中使用AOP特性非常简单,使用@AspectJ注解,然后再配置中开启AspectJ即可。在日常的应用,有时可以将日志记录和异常处理在一个拦截器中统一处理,但有时在项目中无法通过一个拦截器解决所有切面问题,此时,就需要将日志、异常处理等拦截器功能拆分开来,但有一点是相同的,就是在需要时增加一个抽象层次用于拦截。

    基础知识

    这部分的细节主要是注解的使用,可以参看之后示例。
    参考资料
    http://www.cnblogs.com/best/p/5736422.html

    实践

    AOP配置

    @Configuration
    @EnableAspectJAutoProxy
    public class AOPConfig {
    }
    

    Log(AOP)实例

    @Aspect
    @Component
    public final class LogInterceptor {
    	private final static int DEFAULT_MAX_LOG_LENGTH = 8192;
    
    	@Pointcut("execution(*  com.bjork.ws.XXXWSImplForSpring.*(..))")
    	public void serviceMethodPointcut() {
    	}
    
    	@Pointcut("execution( * com.bjork.ws.agent..*.*(..)) && @annotation(com.bjork.ws.core.AgentOriginalMethod)")
    	public void agentOriginalMethodPointcut() {
    	}
    
    	@Around("serviceMethodPointcut() || agentOriginalMethodPointcut()")
    	// @Around("agentOriginalMethodPointcut()")
    	public Object Interceptor(ProceedingJoinPoint pjp) throws Throwable {
    		// 获取aop相关信息
    		Signature signature = pjp.getSignature();
    		MethodSignature methodSignature = (MethodSignature) signature;
    		Method targetMethod = methodSignature.getMethod();
    		Class<?> returnType = targetMethod.getReturnType();
    		Object result = null;
    		Logger logger = LoggerFactory.getLogger(pjp.getTarget().getClass());
    
    		try {
    			// 设置默认返回值
    			result = returnType.newInstance();
    
    			logger.info(String.format("%s方法调用开始!", targetMethod.getName()));
    			// 约定只有一个参数
    			Object uniqueParameter = pjp.getArgs()[0];
    			logRequest(JsonHelper.serialize(uniqueParameter), logger);
    			result = pjp.proceed();
    			logResponse(JsonHelper.serialize(result), logger);
    		} finally {
    			logger.info(String.format("%s方法调用结束!", targetMethod.getName()));
    		}
    		return result;
    	}
    
    	protected void logRequest(String requestString, Logger logger) {
    		if (requestString.length() <= DEFAULT_MAX_LOG_LENGTH)
    			logger.info(String.format("请求体为:%s", requestString));
    	}
    
    	protected void logResponse(String responseString, Logger logger) {
    		if (responseString.length() <= DEFAULT_MAX_LOG_LENGTH)
    			logger.info(String.format("响应体为:%s", responseString));
    	}
    }
    

    Exception (AOP)实例

    @Aspect
    @Component
    public final class ServiceInterceptor {
    	@Pointcut("execution(* com.bjork.ws.service..*(..)) "
    		+ "&& @annotation(com.bjork.ws.core.ServiceOpenMethod)")
    	public void serviceMethodPointcut() {
    	}
    
    	@Around("serviceMethodPointcut()")
    	public GenericResult Interceptor(ProceedingJoinPoint pjp) {
    		// 获取aop相关信息
    		Signature signature = pjp.getSignature();
    		MethodSignature methodSignature = (MethodSignature) signature;
    		Method targetMethod = methodSignature.getMethod();
    		// Class<?> returnType = targetMethod.getReturnType();
    		GenericResult result = new GenericResult();
    		Logger logger = LoggerFactory.getLogger(pjp.getTarget().getClass());
    
    		try {
    			// 设置默认返回值
    			// result = returnType.newInstance();
    
    			// 约定只有一个参数
    			Object uniqueParameter = pjp.getArgs()[0];
    			result = (GenericResult) pjp.proceed();
    		} catch (ValidException vex) {
    			result.getResultInfo().setIsSuccessful(false);
    			result.getResultInfo().setCode(vex.getErrorCode());
    			result.getResultInfo().setMessage(vex.getMessage());
    			logger.info(vex.getMessage());
    		} catch (BizException bex) {
    			result.getResultInfo().setIsSuccessful(false);
    			result.getResultInfo().setCode(bex.getErrorCode());
    			result.getResultInfo().setMessage(bex.getMessage());
    			logger.warn(bex.getMessage());
    		} catch (ExternalCallException ecex) {
    			result.getResultInfo().setIsSuccessful(false);
    			result.getResultInfo().setCode(ecex.getErrorCode());
    			result.getResultInfo().setMessage(ecex.getMessage());
    			logger.warn(ecex.getMessage());
    		} catch (Throwable ex) {
    			result.getResultInfo().setIsSuccessful(false);
    			result.getResultInfo().setCode(ExceptionInfo.SYSTEM_EXCEPTION_CODE);
    			result.getResultInfo().setMessage(ExceptionInfo.SYSTEM_EXCEPTION_MESSAGE);
    			logger.error(ex.getMessage(), ex);
    		} finally {
    		}
    		return result;
    	}
    }
    

    AutoConfiguration配置

    @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
    //@SpringBootApplication
    @ComponentScan("com.xxx.ws")
    public class ServiceInitializer extends SpringBootServletInitializer {
    
    	@Override
    	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    		return application.sources(ServiceInitializer.class);
    	}
    
    	@Bean
    	public LogAspect logAspect() {
    		return new LogAspect();
    	}
    
    	@Bean
    	public ServiceExceptionAspect serviceExceptionAspect() {
    		return new ServiceExceptionAspect();
    	}
    }
  • 相关阅读:
    vue 中按需引入 echarts
    [Vue warn]: Error in nextTick: "TypeError: Cannot read property 'init' of undefined"
    js计算图片大小(promise)
    git push 提示'You are not allowed to push code to this project'
    echarts canvas 层级太高 导致tooltip被遮盖
    卡片展示(不定宽),最后一行左对齐 的几种实现方式
    styled-components 使用小结
    echarts 平均值及 y轴刻度n等分配置
    react 中使用阿里彩色图标
    php unlink()函数使用
  • 原文地址:https://www.cnblogs.com/xiong2ge/p/springaop_inaction.html
Copyright © 2020-2023  润新知