Spring AspectJ 框架

本文详细介绍了AspectJ在Spring框架中的应用,包括AspectJ的基本概念、通知类型、XML配置、注解配置以及Schema_based配置方式。通过实例展示了如何编写切面类、配置切点和通知,以及如何在Spring中启用注解处理。
摘要由CSDN通过智能技术生成

1.什么是AspectJ

AspectJ 是一个基于 Java 语言的 AOP 框架。在 Spring 2.0 以后,新增了对 AspectJ
架的支持。在 Spring 框架中建议使用 AspectJ 框架开发 AOP
2.AspectJ 框架中的通知类型

3.AspectJ 框架配置 AOP 方式

 3.1通过 XML 文件配置 AOP
                
通过 AspectJ 配置方式
通过 Spring Schema_based 方式
3.2 通过注解配置 AOP
4.AspectJ 配置方式
AspectJ 配置方式是指使用 AspectJ 框架的配置方式来配置切面。在使用 AspectJ 配置切
面时,切面不需要实现一些特定的接口。
        1.编写切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspect {
    /**
     * 前置通知
     * @param joinPoint 对目标对象的封装
     */
    public void myBefore(JoinPoint joinPoint){
        //joinPoint.getTarget(); 获取目标对象
        //joinPoint.getSignature().getName(); 获取目标方法名
        //joinPoint.getArgs(); 获取目标方法参数列表
        //joinPoint.getThis(); 获取代理对象
        System.out.println("Before "+joinPoint.getSignature().getName());
    }

    /**
     * 后置通知
     * @param joinPoint
     */
    public void myAfterReturning(JoinPoint joinPoint){
        System.out.println("After "+joinPoint.getSignature().getName());
    }

    /**
     * 环绕通知
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
        System.out.println("Around Before "+proceedingJoinPoint.getSignature().getName());
        Object  obj = proceedingJoinPoint.proceed();
        System.out.println("Around After "+proceedingJoinPoint.getSignature().getName());
        return  obj;
    }

    /**
     * 异常通知类型
     * @param e
     */
    public void myAfterThrowing(Exception e){
        System.out.println("Exception "+e);
    }

    public void myAfter(){
        System.out.println("最终通知");
    }
}

                2.编写配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--配置目标对象-->
    <bean id="usersService" class="com.aspectj.service.impl.UsersServiceImpl"/>
    
    <!--配置切面对象-->
    <bean id="myAspect" class="com.aspectj.aop.MyAspect"/>
    <!--配置切面对象-->
    <bean id="myAspect2" class="com.aspectj.aop.MyAspect2"/>
    <!-- 配置切面-->
    <aop:config>
        <aop:aspect id="my1" ref="myAspect" order="1">
           <!-- 配置切点-->
            <aop:pointcut id="myPointcut" expression="execution(* com.aspectj.service.*.*(..))"/>
            <!--前置通知-->
            <aop:before method="myBefore" pointcut-ref="myPointcut"/>
            <!--后置通知-->
            <aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut"/>
            <!--环绕通知-->
            <aop:around method="myAround" pointcut-ref="myPointcut"/>
            <!--配置异常通知-->
            <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointcut" throwing="e"/>
            <!--最终通知-->
            <aop:after method="myAfter" pointcut-ref="myPointcut"/>
        </aop:aspect>
        <!--配置切面-->
        <aop:aspect id="my2" ref="myAspect2" order="2">
            <aop:pointcut id="myPointcut2" expression="execution(* com.aspectj.service.*.*(..))"/>
            <aop:before method="myAspectBefore" pointcut-ref="myPointcut2"/>
        </aop:aspect>
    </aop:config>
</beans>

注意:在 AspectJ 配置方式中,可以添加多个<aop:aspect>标签实现多切面配置。在<aop:aspect> 标签中包含 order 属性用于配置执行切面的执行顺序。

5.Schema_based 配置方式

Schema_based( 基础模式 ) 配置方式是指使用 Spring AOP 模块来定义切面并在 AspectJ 框架中对该切面进行配置。要求切面在定义通知类型时, 需要实现特定接。
        编写切面类
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;

import java.lang.reflect.Method;

public class BasedMyAspect implements MethodBeforeAdvice, AfterReturningAdvice, MethodInterceptor, ThrowsAdvice {
    /**
     * 环绕通知
     * @param methodInvocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("Around Before");
       Object obj =  methodInvocation.proceed();
        System.out.println("Around After");
        return obj;
    }

    /**
     * 后置通知
     * @param o
     * @param method
     * @param objects
     * @param o1
     * @throws Throwable
     */
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("After.");
    }

    /**
     * 前置通知
     * @param method
     * @param objects
     * @param o
     * @throws Throwable
     */
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("Before");
    }

    /**
     * 异常通知
     * @param ex
     */
    public void afterThrowing(Exception ex){
        System.out.println("Exception: "+ex);
    }
}

        配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--配置目标对象-->
    <bean id="basedUsersService" class="com.schema_based.service.impl.BasedUsersServiceImpl"/>

    <!--配置切面对象-->
    <bean id="basedMyAspect" class="com.schema_based.aop.BasedMyAspect"/>

    <!--配置切面对象-->
    <bean id="basedMyAspect2" class="com.schema_based.aop.BasedMyAspect2"/>
    <!--配置切面-->
    <aop:config>
       <!-- 配置切点-->
       <aop:pointcut id="basedMyPointcut" expression="execution(* com.schema_based.service.*.*(..))"/>
        <!--配置切面-->
        <aop:advisor id="my1" advice-ref="basedMyAspect" pointcut-ref="basedMyPointcut" order="1"/>
        <aop:advisor id="my2" advice-ref="basedMyAspect2" pointcut-ref="basedMyPointcut" order="2"/>
    </aop:config>
</beans>

        注意:在 Schema_based 配置方式中,可以添加多个<aop:advisor>标签实现多切面配置。在 <aop:advisor>标签中包含 order 属性用于配置执行切面的执行顺序

6.注解配置方式

AspectJ 框架允许使用注解定义切面、切入点和增强处理,而 Spring 框架则可以识别并 根据这些注解生成 AOP 代理。
常用注解
常用注解注解说明
@Before
前置通知
@AfterReturning 
后置通知 
@Around
环绕通知
@After
最终通知
@Pointcut
配置切点
@Aspect
指定切面
@Order
执行顺序 ( 此注解由 Spring 提供 )

实例:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;

@Aspect //指定当前对象为切面对象
@Order(2)
public class MyAspect {

    /**
     * 配置切点
     */
    @Pointcut("execution(* com.bjsxt.service.*.*(..))")
    public void myPointcut(){

    }

    /**
     * 前置通知
     * @param joinPoint
     */
    //@Before("execution(* com.bjsxt.service.*.*(..))")
    @Before("myPointcut()")
    public void myBefore(JoinPoint joinPoint){
        System.out.println("Before...."+joinPoint.getSignature().getName());
    }

    /**
     * 后置通知
     * @param joinPoint
     */
    //@AfterReturning("execution(* com.bjsxt.service.*.*(..))")
    @AfterReturning("myPointcut()")
    public void myAfterRetuning(JoinPoint joinPoint){
        System.out.println("AfterRetuning "+joinPoint.getSignature().getName());
    }

    /**
     * 环绕通知
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    //@Around("execution(* com.bjsxt.service.*.*(..))")
    @Around("myPointcut()")
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
        System.out.println("Around Before ");
        Object proceed = proceedingJoinPoint.proceed();
        System.out.println("Around After");
        return proceed;
    }

    /**
     * 最终通知
     */
   // @After("execution(* com.bjsxt.service.*.*(..))")
    @After("myPointcut()")
    public void myAfter(){
        System.out.println("最终通知");
    }

    /**
     * 异常通知
     * @param e
     */
    //@AfterThrowing(value = "execution(* com.bjsxt.service.*.*(..))",throwing = "e")
    @AfterThrowing(value = "myPointcut()",throwing = "e")
    public void myAfterThrowing(Exception e){
        System.out.println("Exception: "+e);
    }
}

        相关配置文件

      

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

   <!-- 配置目标对象-->
    <bean id="usersService" class="com.service.impl.UsersServiceImpl"/>

    <!--配置切面对象-->
    <bean id="myAspect" class="com.aop.MyAspect"/>
    <bean id="myAspect2" class="com.aop.MyAspect2"/>
    <!--在AspectJ框架中开启注解处理。声明自动为IOC容器的那些配置了@AspectJ的切面的bean对象创建代理,织入切面。-->
    <!--默认为false:false:使用JDK的Proxy对象创建代理对象。true:使用CGLIB创建代理对象。如果目标对象实现了接口会使用Proxy,如果目标
    对象没有实现接口则自动使用CGLIB创建代理对象。-->
    <aop:aspectj-autoproxy proxy-target-class="false"/>
</beans>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值