ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

记录一次对AOP的使用,使用AOP完成i18n多语言支持的集成

2021-10-23 20:58:33  阅读:258  来源: 互联网

标签:pattern AOP 切点 result 使用 i18n 方法 public 切面


上回说到


算了。不说了。。。。之前用增强Controller完成了有i18n的支持,后来想想,要不要试试用拦截器和aop各自实现一次试试,说干就干
首先准备了依赖

依赖

文章目录

 <!-- aop -->
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-aop</artifactId>
 </dependency>
 <dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>fastjson</artifactId>
     <version>1.2.47</version>
 </dependency>

定义一个切面

我们使用@Aspect注解在上将一个类定义为切面类,
使用@Pointcut(切面表达式)定义切入点
使用@Around(切入点)指定一个切面内容切入哪个切入点
方法有一个参数ProceedingJoinPoint pjp 这个就代表被切入的方法,我们可以使用pjp.proceed()使原方法执行,注意这里是使原方法执行,执行到这里就会直接执行原来的方法,如果有返回值可以直接获取;
如果不调用则不会执行原方法内容,调用了原方法之后,就会暂停在等待返回哪个阶段,,所以此时如果使用的使ResponseEntity响应的,并不会被解析为其中的泛型,返回值依然是ResponseEntity,不像增强Controller,获取到的object是解析后的泛型所指类型;
响应顺序…方法响应=>aop=>增强controller=>拦截器=>过滤器

完整代码


/**
 * 定义一个切面打印请求返回参数信息
 */

@Aspect  // 定义为一个切面
@Configuration
public class LogRecordAspect {

    private final ResultUtils resultUtils;

    public LogRecordAspect(ResultUtils resultUtils) {
        this.resultUtils = resultUtils;
    }

    private static final Logger logger = LoggerFactory.getLogger(LogRecordAspect.class);

    // 定义切点Pointcut
    @Pointcut("execution(public * com.doria.learnProject.codeStyle.LanguageMapper.*Controller.*(..))")
    public void resultPointcut() {
    }

    /**
     * 切面内容,当触发上面的切面以后就会走到这里的代码
     *
     * @param pjp 方法体
     * @return 就是方法返回值
     * @throws Throwable
     */
    @Around("resultPointcut()") // 指定切面需要插入的切点
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        // 获取当前线程所绑定的requestAttributes
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        // 强转以获取Request
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        // 获取request[其实看到这个demo我也很疑惑为什么不直接拿去注入的HttpServletRequest,但是我很菜,不敢怀疑,听大佬的]
        assert sra != null;
        HttpServletRequest request = sra.getRequest();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        String json = JSON.toJSONString(request.getParameterMap());
        logger.info("收到请求=>Uri:{},请求方式:{},参数:{}", uri, method, json);

        // 获取方法的返回值result的值就是返回值
        Object result = pjp.proceed();
        logger.info("请求结束=>返回值为:" + JSON.toJSONString(result));

        // 由于特殊需要,这里需要对参数的返回值进行处理,这里是吧code转为对应的语言填入msg
        if (result instanceof Result)
            // 调用语言转换方法,大概内容就是强转然后读取code然后通过i18n转换为msg写入msg
            return resultUtils.languageFormatToResult(result);
        return result;
    }
}

语言填充方法


@Autowired
private MessageSource messageSource;

/**
 * 语言转换方法
 * @param o 待处理对象
 * @return 处理后的对象
 */
public Object languageFormatToResult(Object o){
    // 由于调用方法前使用了instanceof确定了具体类型,我们这里可以直接强转
    Result<?> result = (Result<?>) o;
    // 强转以后取出code
    String key = result.getCode().toString();
    // 设置msg,用code作为key获取参数
    result.setMsg(messageSource.getMessage(key,null, LocaleContextHolder.getLocale()));
    return result;
}

关于切点和切点表达式

切入点

可以通过这个注解定义一个切入点,其中可以没内容

// 定义切点Pointcut
    @Pointcut("execution(public * com.doria.learnProject.codeStyle.LanguageMapper.*Controller.*(..))")
    public void resultPointcut() {
    }

切点表达式

由于Spring切面粒度最小是达到方法级别,而execution表达式可以用于明确指定方法返回类型,类名,方法名和参数名等与方法相关的部件,并且在Spring中,大部分需要使用AOP的业务场景也只需要达到方法级别即可,因而execution表达式的使用是最为广泛的。如下是execution表达式的语法:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)

这里问号表示当前项可以有也可以没有,其中各项的语义如下:

modifiers-pattern:方法的可见性,如public,protected;
ret-type-pattern:方法的返回值类型,如int,void等;
declaring-type-pattern:方法所在类的全路径名,如com.spring.Aspect;
name-pattern:方法名类型,如buisinessService();
param-pattern:方法的参数类型,如java.lang.String;
throws-pattern:方法抛出的异常类型,如java.lang.Exception;

切入点表达式详解

标签:pattern,AOP,切点,result,使用,i18n,方法,public,切面
来源: https://blog.csdn.net/m0_49194578/article/details/120923474

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有