Spring关于AOP的简单例子

1.AOP(面向切面编程)
AOP(Aspect-OrientedProgramming),利用一种称为"横切"的技术,剖解开封装的对象内部,将那些影响了多个类的公共行为封装到一个可重用模块,命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日 志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。
2.关于AOP的一个简单例子:
首先编写一个AOP切面类(注解形式)

package com.gx.aop;

import java.util.Date;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component  //Spring注解
@Aspect   //AOP切面注解
@Order(1) //设置优先级,正整数,数字越小,优先级越高
public class MyAopAspect1 {
    
    

    private static final Logger logger = LoggerFactory.getLogger(MyAopAspect1.class);

    //配置切入点,该方法无方法体,主要为方便同类中其他方法使用此处配置的切入点
    //匹配com.gx.service包下所有的类的所有的方法
    @Pointcut("execution(* com.gx.service.*.*(..))")
    public void aspect(){
    
    

    }
    
    /**
     * 前置通知, 在方法执行之前执行
     * 使用在方法aspect()上注册的切入点
     * @param joinPoint
     */
    @Before(value="aspect()")
    public void beforeMethod(JoinPoint joinPoint){
    
    
        //获取目标的类名
        String className = joinPoint.getTarget().getClass().getName();
        //得到方法签名
        String methodName = joinPoint.getSignature().getName();
        logger.info("=======>>> beforeMethod*******"+className
        		+"("+methodName+") run start*******!");
    }

    /**
     * 后置通知, 在方法执行之后执行
     * 使用在方法aspect()上注册的切入点
     * @param joinPoint
     */
    @After(value="aspect()")
    public void afterMethod(JoinPoint joinPoint){
    
    
        //获取目标的类名
        String className = joinPoint.getTarget().getClass().getName();
        //得到方法签名
        String methodName = joinPoint.getSignature().getName();
        logger.info("=======>>> afterMethod*******"+className+"("+methodName+")*******!");
    }

    /**
     * 后置返回通知, 在方法返回结果之后执行
     * 使用在方法aspect()上注册的切入点
     *
     * AfterReturning增强处理可以访问到方法的返回值,但它不可以改变目标方法的返回值
     * @param joinPoint
     * @param objValue 方法返回值
     */
    @AfterReturning(value="aspect()",returning="objValue")
    public void afterReturningMethod(JoinPoint joinPoint,Object objValue){
    
    
        //获取目标的类名
        String className = joinPoint.getTarget().getClass().getName();
        //得到方法签名
        String methodName = joinPoint.getSignature().getName();
        logger.info("=======>>> afterReturningMethon*******"+className
        		+"("+methodName+")  Return="+objValue.toString()+"*******!");
    }

    /**
     * 后置异常通知, 在方法抛出异常之后
     * 使用在方法aspect()上注册的切入点
     * @param joinPoint
     * @param e
     */
    @AfterThrowing(value="aspect()",throwing="e")
    public void afterThrowingMethod(JoinPoint joinPoint,Exception e){
    
    
        //获取目标的类名
        String className = joinPoint.getTarget().getClass().getName();
        //得到方法签名
        String methodName = joinPoint.getSignature().getName();
        logger.info("=======>>> afterReturningMethon*******"+className
        		+"("+methodName+") 出现异常----+"+e.getMessage()+"*******!");
    }

    /**
     * 环绕通知, 围绕着方法执行
     * 使用在方法aspect()上注册的切入点
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around(value="aspect()")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable{
    
    
        String metodName = joinPoint.getSignature().getName();
        logger.info("aroundMethod<<<<<<<<method("+metodName+")startTime="+new Date()+">>>>>>>>");
        //调用被切入的方法
        Object object = joinPoint.proceed();
        logger.info("aroundMethod<<<<<<<<method("+metodName+")endTime="+new Date()+">>>>>>>>");
        return object;
    }
}

因为MyAopAspect1使用了log4j的方法,需要添加log4j的jar包和配置文件,如下所示:
在这里插入图片描述
在 applicationContext.xml文件中配置AOP

<!-- 开启注解 -->
<context:annotation-config />
<!-- 配置扫描路径, 去扫描有注解的包名-->
<context:component-scan base-package="com.gx.dao,com.gx.service,com.gx.aop" />

<!-- 自动为 spring容器中那些配置@Aspect切面的bean创健建代理,放入切面 -->
<aop:aspectj-autoproxy />

执行结果截图,如下所示:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_44547592/article/details/109320626