简单使用AspectJ

这篇博客主要写给自己看的,方便以后回顾

AspectJ是一个AOP框架,由于SpringAOP的配置过于繁琐,因此使用了AspectJ依赖注解开发

1、Aspecj依赖坐标,此处省略了Spring相关依赖

<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.7.1</version>
</dependency>

2、在applicationContext.xml文件中配上

<aop:aspectj-autoproxy/>

 代表使用Aspecj的注解开发模式

3、自定义创建的切入点,以及要实现的功能

 
 
package com.util;

import com.dao.LogDAO;

import com.entity.LogMessage;
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.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.UUID;
@Aspect     // 用来声明这是一个AspectJ
@Component  // 在此处声明一个Component 是因为Spring扫描注解并不能识别AspectJ 因此在此处声明,不必在applicationContext.xml配置bean标签了
public class ServiceLog {

    @Autowired   
    private LogDAO logDAO;
    //在该无参无内容的方法上添加一个@Poincut()来声明切入点,在后来的@Around("pc()")直接写入该方法的名字就能在自动使用这些切点
    @Pointcut("execution(* com.service..*.add*(..)) || execution(* com.service..*.modify*(..)) || execution(* com.service..*.drop*(..))")
    public void pc() {}
    //环绕通知注解
    @Around("pc()")
    public Object log(ProceedingJoinPoint pjp) throws Throwable {
        // 获取request
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();

        // 获取Session
        HttpSession session = request.getSession();

        // 获取用户名
        String adminName = (String) session.getAttribute("adminName");

        // UUID
        String uuidName = UUID.randomUUID().toString().replace("-","");

        LogMessage log = new LogMessage();

        log.setLogId(uuidName);
        log.setLogUser(adminName);
        log.setLogTime(new Date());

        String totalArg = null;
        //获取参数
        Object[] args = pjp.getArgs();
        for (Object arg : args) {
            totalArg += arg;
            totalArg += " ";
        }
       log.setLogMessage(totalArg);
        // 返回目标方法的签名
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        // 获取方法对象
        Method method = methodSignature.getMethod();
        // 获取方法名称
        String methodName = method.getName();

        String firstCode = methodName.substring(0,1);

        if (firstCode.equals("a")) {
           log.setLogAction("添加");
        } else if (firstCode.equals("m")) {
            log.setLogAction("修改");
        } else {
            log.setLogAction("删除");
        }
//        获取方法所在的类 及类型
//        System.out.println(methodSignature.getDeclaringType());
        // 获取方法所在的类
        String oldName = methodSignature.getDeclaringTypeName();
        String suffix = oldName.substring(oldName.lastIndexOf(".") + 1);
        log.setLogResource(suffix);
//        // 获取方法的注解
//        Annotation[] annotation = method.getAnnotations();
        Object obj = null;
        try {
            obj = pjp.proceed();
            log.setLogResult("success");
        } catch (Exception e) {
            e.printStackTrace();
            log.setLogResult("error");
        }
        logDAO.inserLog(log);
        return obj;
    }
}

该类实现的是用户操作后台的日志记录,实现了用户在进行增删改时记录用户信息,操作的类以及方法参数。

这样一个简单的AspectJ就实现了。

 AspactJ框架常用注解

@PonitCut  // 声明切入点的注解
@Before    // 声明前置通知注解
@After     // 声明后置通知注解(原始方法执行正常或者非正常执行都会进入)
@AfterReturing // 声明后置通知注解(原始方法必须正常执行)
@AfterThrowing // 声明异常通知
@Around // 环绕通知注解

 

猜你喜欢

转载自blog.csdn.net/qq_41181619/article/details/81021680