Aop归纳

  • aop是动态代理的一种应用。对于有接口的类,使用原生的代理类,利用反射获取到类加载器,然后构造出构造函数,通过构造函数返一个代理对象,另一种没有实现接口的类使用的就是cglib代理,代理类继承自原类。
  • 使用:(aspect + component)
    pointcut 切点 (进行切点匹配)
    advice 通知 (对匹配到的进行织入) joinpoint 连接点|proceedingjoinpoint 进行连接点 ≈ target weaving 织入
@Aspect
@Slf4j
@Component
public class WebLogAspect {

    @Pointcut("execution( * com.az.controller..*(..))")
    public void webLog() {}

    @Around("webLog()")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("方法执行: " + joinPoint.getSignature().getDeclaringType().getName() + "#" + joinPoint.getSignature().getName());

		Object[] args = joinPoint.getArgs();
        Object   arg  = args[0];

        Object proceed = joinPoint.proceed();
        log.info("方法: " + joinPoint.getSignature().getName() + "() 执行完毕");
        return proceed;
    }

    @AfterThrowing(pointcut = "webLog()", throwing = "e")
    public void afterThrowingMethod(JoinPoint joinPoint, Throwable e) {
        log.error("方法异常:" + joinPoint.getSignature().getDeclaringType().getName() + "#" + joinPoint.getSignature().getName() + " 异常");
        log.error("异常信息:" + e.getMessage());
    }

    @Before("execution(* com.az.controller.add(..))")
    public void beforeAddOperation(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        log.info("Before executing the add() method");
        log.info("Arguments: " + Arrays.toString(args));
    }

}

位置图 Big picture

  • 不同注解之间重要是位置。
try{
    try{
        //@Around start
        //@Before
        method.invoke(..);
        //@Around end
    }finally{
        //@After
    }
    //@AfterReturning
}catch(){
    //@AfterThrowing
}

获得运行时 JoinPoint’s Signature

  • 获得常用目标
// ProceedingJoinPoint point;
// 获取当前执行类
String typeName = point.getTarget().getName();
// String typeName = point.getSignature().getDeclaringTypeName();

// 获取当前执行类的执行方法名
String name = point.getSignature().getName();
// 获取当前执行方法的执行参数
Object[] object = point.getArgs();

// 获取当前执行 method
Signature signature = point.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
// 获取方法注解
if (method.isAnnotationPresent(DataSource.class)) {
    DataSource dataSource = method.getAnnotation(DataSource.class);
    String value = dataSource.value();
  • 获取入参对象的 class
Method targetMethod = ((MethodSignature) (point.getSignature())).getMethod();
Class<?>[] parameterTypes = targetMethod.getParameterTypes();
// 转变为集合
List<Class<?>> collect = Arrays.stream(parameterTypes).collect(Collectors.toList());
// 入参对象
Class<?> aClass1 = collect.get(0);

Summary

package aop;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.*;

/**
 * Advice -> Interceptor -> MethodInterceptor (core is Advice, specific aspect code, this is static)
 * <p>Joinpoint-> Invocation -> MethodInvocation (core is Joinpoint, specific cut into the context, this is the runtime)
 * <p>advice is the action to take at a joinpoint</p>
 */
public class AopAlliance {

    /**
     * Action taken by an aspect at a particular join point.
     */
    private Advice advice;

    private Interceptor interceptor;
    private MethodInterceptor methodInterceptor;

    /**
     * A point during the execution of a program,
     * such as the execution of a method or the handling of an exception.
     * In Spring AOP, a join point always represents a method execution.
     */
    private Joinpoint joinpoint;

    /**
     * This interface represents an invocation in the program.
     * <p>An invocation is a joinpoint and can be intercepted by an interceptor.
     */
    private Invocation invocation;

    /**
     * Description of an invocation to a method, given to an interceptor upon method-call.
     * <p>A method invocation is a joinpoint and can be intercepted by a method interceptor.
     */
    private MethodInvocation methodInvocation; // ReflectiveMethodInvocation

    /**
     * A modularization of a concern that cuts across multiple classes.
     * Transaction management is a good example of a crosscutting concern in enterprise Java application.
     */
    private enum Aspect {
        /**
         * <p>Spring Addition</p>
         * A predicate that matches join points.
         * Advice is associated with pointcut expression and runs at any join point matched by the pointcut.
         * (for example, the execution of a method with a certain name)
         * <p>
         * Pointcut vs Joinpoint: static vs runtime(instance)
         */
        Pointcut,
        /**
         * Advisor -> PointcutAdvisor
         * <p>Holders of Advice, the main reference sub-interface PointcutAdvisor
         * <p>An Advisor advises someone (Pointcut) to do something at a certain time (Advice)
         */
        Advisor,
        /**
         * Declare additional methods or fields on behalf of a type.
         * Spring AOP lets you introduce new interfaces (and a corresponding implementation)
         * to any advised object. For example, you could use an introduction to make a bean implement an IsModified interface, to simplify caching.
         */
        Introduction,
        /**
         * An object being advised by one or more aspects. Also referred to as the "advised object".
         * Since Spring AOP is implemented by using runtime proxies, this object is always a proxies object.
         */
        Target_object,
        /**
         * An object created by the AOP framework in order to implement the aspect contracts.
         * In the Spring Framework, an AOP proxy is a JDK dynamic proxy or a CGLIB proxy.
         */
        AOP_proxy,
        /**
         * linking aspects with other application types or objects to create an advised object.
         * This can be done at compile time (using the AspectJ compiler, for example), load time, or at runtime.
         * Spring AOP, like other pure Java AOP frameworks, performs weaving at runtime.
         */
        Weaving;
    }

    /**
     * Spring AOP's approach to AOP differs from that of most other AOP frameworks. The aim is not
     * to provide the most complete AOP implementation (although Spring AOP is quite capable).
     * Rather, the aim is to provide a close integration between AOP implementation and Spring IoC,
     * to help solve common problems in enterprise applications.
     * <p>
     * If you get a bean and want to know if it has been enhanced,
     * you can determine if the bean is subclass of {@code Advised}
     */
    public AopAlliance() {

        Aspect[] aspects =
                {Aspect.Pointcut, Aspect.Advisor, Aspect.Introduction, Aspect.Target_object,
                 Aspect.AOP_proxy, Aspect.Weaving};
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值