Spring整合aspectj框架实现的aop

在现在的开发中使用这种方案比较多.
在spring2.0以后它支持jdk1.5注解,而整合aspectj后可以使用aspectj语法,可以简化开发。

Aspect:切面 =切点+通知(多个切点与多个通知的组合)
AspectJ 它是一个第三方框架,spring从2.0后可以使用aspectJ框架的部分语法.

AspectJ框架它定义的通知类型有6种

  1. 前置通知Before 相当于BeforeAdvice
  2. 后置通知AfterReturning 相当于AfterReturningAdvice
  3. 环绕通知 Around 相当于MethodInterceptor
  4. 抛出通知AfterThrowing 相当于ThrowAdvice
  5. 引介通知DeclareParents 相当于IntroductionInterceptor
  6. 最终通知After 不管是否异常,该通知都会执行
    相比spring 的传统AOP Advice多了一个最终通知
    基于xml配置方案
    第一步:创建目标(target)
    接口
package com.itcast.aspectj;

public interface IUserService {
    public void add();
    public void update();
    public void del();
    public void search();
}

实现类

package com.itcast.aspectj;

public class IUserServiceImpl implements IUserService {
    @Override
    public void add() {
        System.out.println(0/0);
        System.out.println("aspectj IUserService add");
    }

    @Override
    public void update() {
        System.out.println("aspectj IUserService update");
    }

    @Override
    public void del() {
        System.out.println(0/0);
        System.out.println("aspectj IUserService del");
    }

    @Override
    public void search() {
        System.out.println("aspectj IUserService search");
    }
}

第二步:创建通知(增强 advice)
注意:在aspectj中它的增强可以不实现任何接口,只需要定义出增强功能(方法)

package com.itcast.aspectj;

import org.aspectj.lang.ProceedingJoinPoint;

//advice通知
public class IUserServiceHapper {
    public void before(){
        System.out.println("前置通知。。。");
    }
    public void before1(){
        System.out.println("前置通知1。。。");
    }
    public void afterReturning(){
        System.out.println("后置通知。。。");
    }

    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("环绕前。。。");
        Object value = point.proceed();//执行目标行为
        System.out.println("环绕后。。。");
        return value;
    }

    public void afterThorwing(){

        System.out.println("异常通知");
    }

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


第三步:在spring的xml 配置文件中来配置
aop:config下的aop:aspect是aspectJ框架用来声明切面的。

<?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:context="http://www.springframework.org/schema/context"
       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
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--目标target-->
    <bean id="userService" class="com.itcast.aspectj.IUserServiceImpl"></bean>

    <!--通知Advice-->
    <bean id="userServiceAdvice" class="com.itcast.aspectj.IUserServiceHapper"></bean>

    <!--通过AOP的标签来完成我们的配置-->
    <aop:config>    <!--它帮我们完成自动代理功能-->
        <!--抽取切点-->
        <aop:pointcut id="addpointcut" expression="execution(* *.add(..)) "></aop:pointcut>
        <aop:pointcut id="delpointcut" expression="execution(* *.del(..)) "></aop:pointcut>
        <aop:aspect ref="userServiceAdvice">
            <!--前置通知-->
            <aop:before method="before"  pointcut-ref="addpointcut"/>
            <aop:before method="before1" pointcut-ref="addpointcut"/>
            <!--后置通知-->
            <aop:after-returning method="afterReturning" pointcut-ref="addpointcut"/>
            <!--环绕通知-->
            <aop:around method="around" pointcut-ref="addpointcut"/>
            <!--最终通知-->
            <aop:after method="after" pointcut-ref="addpointcut"/>
            <!--异常通知-->
            <aop:after-throwing method="afterThorwing" pointcut-ref="delpointcut"/>
        </aop:aspect>       
    </aop:config>
</beans>

通知类型:
在这里插入图片描述

也可把切点抽取出来做成公共的,各通知可进行引用,可设置多个< aop:pointcut>
修改如下:

    <aop:config>    <!--它帮我们完成自动代理功能-->
        <aop:pointcut id="addpointcut" expression="execution(* *.add(..)) "></aop:pointcut>
        <aop:pointcut id="delpointcut" expression="execution(* *.del(..)) "></aop:pointcut>
        <aop:aspect ref="userServiceAdvice">
            <aop:before method="before"  pointcut-ref="addpointcut"/>
            <aop:before method="before1" pointcut-ref="addpointcut"/>
            <aop:after-returning method="afterReturning" pointcut-ref="addpointcut"/>
            <aop:around method="around" pointcut-ref="addpointcut"/>
            <aop:after method="after" pointcut-ref="addpointcut"/>
            <aop:after-throwing method="afterThorwing" pointcut-ref="delpointcut"/>
        </aop:aspect>
    </aop:config>

关于通知上的参数

  1. 在前置通知上可以添加JoinPoint参数
    通过它可以获取目标相关的信息
public void before(JoinPoint jp){
        System.out.println("拦截的目标类:"+jp.getSignature().getDeclaringTypeName());
        System.out.println("拦截的方法名称:"+jp.getSignature().getName());
        System.out.println("前置通知");
    }

使用前置通知可以完成日志记录,权限控制

  1. 在后置通知上添加的参数
public void afterReturning(JoinPoint jp,Object val){
        System.out.println("返回val。。。");
        System.out.println("后置通知。。。");
    }

第二个参数val它可以获取目标方法的返回值
注意:需要在配置文件中配置

<!--后置通知-->
<aop:after-returning method="afterReturning" pointcut-ref="addpointcut" returning="val"/>
  1. 环绕通知上的参数
 public Object around(ProceedingJoinPoint pjp) throws Throwable {
        //它是我们开发中应用最多的,可以完成日志操作,权限操作,性能监控,事务管理
        System.out.println("环绕前。。。");
        Object value = pjp.proceed();//执行目标行为
        System.out.println("环绕后。。。");
        return value;
    }

它是我们开发中应用最多的,可以完成日志操作,权限操作,性能监控,事务管理

4.抛出异常通知上的参数

 public void afterThorwing(JoinPoint jp,Throwable throwable){
        //第二个参数Throwable它是用于接收抛出的异常,注意:需要在配置文件中声明
        System.out.println("异常通知");
    }

第二个参数Throwable它是用于接收抛出的异常
注意:需要在配置文件中声明

 <!--异常通知-->
<aop:after-throwing method="afterThorwing" pointcut-ref="delpointcut" throwing="throwable"/>
  1. 最终通知上的参数
public void after(JoinPoint joinPoint){
        //可以使用最终通知完成资源释放
        System.out.println("最终通知。。。");
    }

可以使用最终通知完成资源释放

猜你喜欢

转载自blog.csdn.net/Marion158/article/details/85642674