【java】Aspect切面示例

1.注解

package com.test.annotation;

import java.lang.annotation.*;

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UpdateStudentAnnotation {
    String value() default "";
}

2.切面

package com.test;

import com.test.UpdateStudentAnnotation;
import com.test.KnowledgeService;
import com.test.Student;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 */
@Aspect
@Component
@Lazy(false)
@Slf4j
public class UpdateStudentAspect {

    @Autowired
    private StudentService studentService;

    @Pointcut("@annotation(com.test.UpdateStudentAnnotation)")
    private void cutMethod() {

    }

    /**
     * 前置通知:在目标方法执行前调用
     */
    @Before("cutMethod()")
    public void begin() {
    }

    /**
     * 后置通知:在目标方法执行后调用,若目标方法出现异常,则不执行
     */
    @AfterReturning("cutMethod()")
    public void afterReturning() {
    }

    /**
     * 后置/最终通知:无论目标方法在执行过程中出现一场都会在它之后调用
     */
    @After("cutMethod()")
    public void after() {
    }

    /**
     * 异常通知:目标方法抛出异常时执行
     */
    @AfterThrowing("cutMethod()")
    public void afterThrowing() {
    }

    /**
     * 环绕通知:灵活自由的在目标方法中切入代码
     */
    @Around("cutMethod()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 执行源方法
        Object obj = null;
        try {
            obj = joinPoint.proceed();
            // 获取方法传入参数
            Object[] params = joinPoint.getArgs();
            Long studentId = ((Student) params[0]).getStudentId();
            if (studentId != null) {
                Student student = studentService.getById(studentId);
                studentService.updateStudent(student);
            }
            return obj;
        } catch (Exception e) {
            log.error(e.getMessage());
            return obj;
        }
    }

    /**
     * 获取方法中声明的注解
     *
     * @param joinPoint
     * @return
     * @throws NoSuchMethodException
     */
    public UpdateStudentAnnotation getDeclaredAnnotation(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
        // 获取方法名
        String methodName = joinPoint.getSignature().getName();
        // 反射获取目标类
        Class<?> targetClass = joinPoint.getTarget().getClass();
        // 拿到方法对应的参数类型
        Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
        // 根据类、方法、参数类型(重载)获取到方法的具体信息
        Method objMethod = targetClass.getMethod(methodName, parameterTypes);
        // 拿到方法定义的注解信息
        UpdateStudentAnnotation annotation = objMethod.getDeclaredAnnotation(UpdateStudentAnnotation.class);
        // 返回
        return annotation;
    }
}

3.应用代码

import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@AllArgsConstructor
public class ScoreService {
    @UpdateStudentAnnotation
    public boolean save(Score score) {
        //新增分数操作
        return true;
    }
    @UpdateStudentAnnotation
    public boolean updateById(Score score) {
        //修改分数操作
        return true;
    }
}

你可能感兴趣的:(java,aop)