码迷,mamicode.com
首页 > Web开发 > 详细

AOP(Aspect Oriented Programming:面向切面编程)

时间:2020-11-25 12:05:49      阅读:12      评论:0      收藏:0      [点我收藏+]

标签:import   module   生成   tty   actor   切片   get   ToJson   gif   

@Aspect注解将表示它是一个切面
@Component表示它是一个Spring的组件

切片Aspect,既然Spring那么支持AOP,就肯定都能拿。有人会问如何拿原始的HTTP请求和响应的信息,通过以下代码应该拿得到啊哈哈哈哈
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();


<aop:config>
<!-- order:指定切面bean的优先级,值越小,优先级越高 -->
<aop:aspect id="fourAdviceAspect" ref="fourAdviceBean" order="2">
<aop:around method="processTask" pointcut="execution(* com.wangjun.aop.xml.*.*(..))"/>
<aop:before method="authority" pointcut="execution(* com.wangjun.aop.xml.*.*(..))"/>
<aop:after-returning method="log" returning="rvt" pointcut="execution(* com.wangjun.aop.xml.*.*(..))"/>
</aop:aspect>
</aop:config>

其中<aop:aspect/>标签就是切面,此标签下面的<aop:around/>、<aop:before/>这些就是增强处理,那么在哪里进行增强处理呢?pointcut属性就定义了切入点,也就是在哪里进行增强处理。这里的表达式比如execution(* com.wangjun.aop.xml.*.*(..))含义如下:

指定在com.wangjun.aop.xml包中任意类方法;
第一个*表示返回值不限,第二个*表示类名不限;
第三个*表示方法名不限,圆括号中的(..)表示任意个数、类型不限的形参。

使用场景
日志记录、审计、声明式事务、安全性和缓存等。

AspectJ和Spring AOP的区别
正好代表了实现AOP的两种方式:
AspectJ是静态实现AOP的,即在编译阶段对程序进行修改,需要特殊的编译器,具有较好的性能;
Spring AOP是动态实现AOP的,即在运行阶段动态生成AOP代理,纯java实现,因此无需特殊的编译器,但是通常性能较差。

例子

业务日志表

技术图片

 

 

技术图片
package chin.common;

/**
 * 操作类型枚举
 */
public enum OpearteType {
    QUERY("检索","QUERY"),
    CREATE("录入","CREATE"),
    UPDATE("维护","UPDATE"),
    DELETE("删除","DELETE"),
    REVIEW("审核","REVIEW"),;

    private String name;
    private String code;

    private OpearteType(String name, String code) {
        this.name = name;
        this.code = code;
    }

    public static String getName(String code) {
        for (OpearteType c : OpearteType.values()) {
            if (c.getCode().equals(code)) {
                return c.name;
            }
        }
        return null;
    }

    public static String getCode(String name) {
        for (OpearteType c : OpearteType.values()) {
            if (c.getName().equals(name)) {
                return c.code;
            }
        }
        return null;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
}
技术图片
技术图片
package chin.annotation;

import chin.common.BusinessModule;

import java.lang.annotation.*;

/**
 * 业务模块注解
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
public @interface BusinessModuleAttributes {
    BusinessModule businessModule();
}
技术图片
技术图片
package chin.annotation;

import chin.common.OpearteType;

import java.lang.annotation.*;

/**
 * 业务日志注解
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface BusinessLogAttributes {
    OpearteType opearteType();
    String opearteDescription();
}
技术图片
技术图片
package chin.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.beyondbit.ias.core.base.BaseController;
import com.beyondbit.ias.core.util.IPUtil;
import chin.annotation.BusinessLogAttributes;
import chin.annotation.BusinessModuleAttributes;
import chin.entity.BusinessLog;
import chin.service.BusinessLogService;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.ui.Model;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 业务日志切面
 */
@Aspect
@Component
public class BusinessLogAspect extends BaseController {

    @Autowired
    private BusinessLogService businessLogService;

    @Pointcut("@annotation(chin.annotation.BusinessLogAttributes)")
    public void logPointCut() {

    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        BusinessModuleAttributes moduleAttributes = point.getTarget().getClass().getAnnotation(BusinessModuleAttributes.class);

        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        BusinessLogAttributes logAttributes = method.getAnnotation(BusinessLogAttributes.class);

        //获取请求参数:
        MethodSignature ms = (MethodSignature) point.getSignature();
        //获取请求参数类型
        String[] parameterNames = ms.getParameterNames();
        //获取请求参数值
        Object[] parameterValues = point.getArgs();
        StringBuilder strParams = new StringBuilder();
        //组合请求参数,进行日志打印
        if (parameterNames != null && parameterNames.length > 0) {
            for (int i = 0; i < parameterNames.length; i++) {
                if (parameterNames[i].equals("bindingResult")) {
                    break;
                }
                if ((parameterValues[i] instanceof HttpServletRequest) || (parameterValues[i] instanceof HttpServletResponse)||(parameterValues[i] instanceof Model)||(parameterValues[i] instanceof MultipartFile)) {
                    strParams.
                            append("[").
                            append(parameterNames[i]).append("=").append(parameterValues[i])
                            .append("]");
                } else {
                    try
                    {
                        strParams.
                                append("[").
                                append(parameterNames[i]).append("=")
                                .append(JSON.toJSONString(parameterValues[i], SerializerFeature.WriteDateUseDateFormat))
                                .append("]");
                    }
                    catch(Throwable throwable){
                        strParams.
                                append("[").
                                append(parameterNames[i]).append("=").append(parameterValues[i])
                                .append("]");
                    }

                }
            }
        }

        Object result = null;
        BusinessLog log = new BusinessLog();
        log.setUuid(java.util.UUID.randomUUID().toString());
        log.setClientIP(IPUtil.getClientIp(request));
        log.setBusinessModule(moduleAttributes.businessModule().getCode());
        log.setOpearteType(logAttributes.opearteType().getCode());
        log.setOpearteDescription(logAttributes.opearteDescription());
        log.setOpeartor(super.getCurrentUser().getUserUid());
        log.setOpeartorName(super.getCurrentUser().getName());
        log.setOpearteDateTime(new Date());
        log.setReqUrl(request.getRequestURL().toString());
        log.setClazz(point.getTarget().getClass().getName());
        log.setMethod(method.getName());
        log.setParams(strParams.toString());
        try {
            // 执行方法
            result = point.proceed();
            log.setStatus("1");
        } catch (Exception e) {

            log.setStatus("0");
            log.setException(e.getStackTrace().toString());
            throw e;
        } finally {
            businessLogService.insertBusinessLog(log);
        }
        return result;
    }

}

 

 

AOP(Aspect Oriented Programming:面向切面编程)

标签:import   module   生成   tty   actor   切片   get   ToJson   gif   

原文地址:https://www.cnblogs.com/hsiaochinchin/p/14013211.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!