zoukankan      html  css  js  c++  java
  • 0102-aop

    背景

    aop的概念很多,比如切点,通知,连接点,引入,织入等;实际上这是一种约定的流程;

    约定编程

    https://github.com/carterbrother/springbootpractice/tree/master/demo-aop

    aop编程

    也是按照一定规则,按照一定 流程来约定编程的;

    典型场景

    • 数据库事物

    提取固定 流程,把变化的部分织入到流程中即可;

    概念

    连接点(join point) : 即方法

    切点 (point cut): 连接点的范围,哪些方法;

    通知(advice): 分为前置通知,后置通知,环绕通知,正常返回通知,异常返回通知

    目标对象(target) :被代理对象

    引入(introduction): 引入新的类和方法,增强现有的bean的功能

    织入(weaving): 通过代理技术,为原有对象生成代理对象

    切面(aspect) : 可以定义切点,各类通知和引用的内容

    springboot的aop的使用

    @Aspect 申明切面

    通知里面放切点:
    @Before 前置通知
    @After 后置通知
    @AfterReturn
    @AfterThrowning
    @Around

    @Pointcut 定义切点
    切点的指示器:

    通知中的参数:
    ProceedingJoinPoint jp 连接点信息
    jp.proceed();//执行原来的方法

    spring采用两种动态代理方式,jdk的动态代理和cglib的动态代理,如果被代理类没有实现接口,spring会切换为cglib的动态代理;

    多个切面,使用@Order(value=x) 来定义顺序,前置通知从升序执行,后置通知降序执行;

    例子:

    package com.lifesense.ihs.tianansp.admin.interceptor;
    
    import com.google.common.base.Strings;
    import com.lifesense.ihs.tianansp.admin.core.TaAdminRestContext;
    import com.lifesense.opensource.commons.utils.JsonUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Service;
    import org.springframework.util.StopWatch;
    
    import java.lang.reflect.Method;
    
    
    /**
     * aop
     */
    @Aspect
    @Service
    @Order(0)
    @Slf4j
    public class ServiceInterceptor {
    
        @Pointcut("execution(public * com.lifesense.ihs.**.admin.manager..*.*(..))")
        public void pointcut() {
        }
    
        private String serviceName() {
            return "tiananspadmin";
        }
    
        @Around("pointcut()")
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            StopWatch stopWatch = new StopWatch();
            Method method = ((MethodSignature) pjp.getSignature()).getMethod();
            final String methodName = method.getDeclaringClass().getCanonicalName().concat(".").concat(method.getName());
            stopWatch.start(methodName);
            Object[] args = pjp.getArgs();
    
            String requestId = TaAdminRestContext.get().getRequestId();
    
            Object returnObj = null;
            try {
                returnObj = pjp.proceed();
            } catch (Exception ex) {
                String message = String.format("[%s]服务发生系统错误:%s", this.serviceName(), ex.getMessage());
                log.error("{}, method:{},args:{} , ServiceContext:{}", message, methodName, JsonUtils.toJson(args), TaAdminRestContext.get(), ex);
                throw ex;
            } finally {
                stopWatch.stop();
                if (log.isDebugEnabled()) {
                    log.debug("timecost_requestId:{} , args:{},returnObj:{},
    {}:", requestId, JsonUtils.toJson(args), JsonUtils.toJson(returnObj), stopWatch.prettyPrint());
                }
            }
            return returnObj;
        }
    }
    
    

    原创不易,转载请注明出处。

  • 相关阅读:
    窗口与窗口之间的关系
    线程同步机制--信号量
    c++的静态变量与静态函数
    MFC实现普通DLL
    常规DLL与扩展DLL区别
    pyget-资源与标签(Sprite、Label、Font)
    linux如何添加系统环境变量
    nginx 入门 安装
    redis基本用法
    linux安装 redis
  • 原文地址:https://www.cnblogs.com/snidget/p/12132140.html
Copyright © 2011-2022 走看看