ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

SpringAop 2.x基于命名空间的配置实现 前置,后置,环绕,异常通知的小案例及解析

2020-02-21 14:01:25  阅读:264  来源: 互联网

标签:joinPoint target 后置 前置 System Object SpringAop org public


SpringAop 2.x

简介:

基于命名空间的配置,原理是使用后处理器,更简单。

特点:

简化配置,

非侵入性编写通知时不需要实现任何接口。

使用AspectJ表达式定义切点。

基本用法:

配置advice

定义增强类,不需要实现任何接口,但有多种写法。
在这里插入图片描述
配置PointCut并织入

AspectJ表达式

简介:切点表达式,一种表达式,用来定义切点位置。

用法:

within 语法:within(包名.类名) 匹配该类中的所有方法。

execution

匹配特定包中的特定类中特定返回值类型的特定参数的特定方法。

语法:execution(表达式)

表达式:返回值类型 包名.类名.方法名(参数类型)

通配符:*和…

…表示参数任意。

配置方式:

基本用法: 添加jar包

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <!--ioc01-core-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <!--ioc01-bean-->
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <!--ioc01-context-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <!--ioc01-expression-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
        </dependency>
        <!--Aop依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <!--cglib技术-->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
        </dependency>

书写接口UserService

package springaop07.service;


/**
 * package_name:springaop01.service
 *
 * author:徐亚远 Date:2020/2/18 18:29
 * 项目名:springDemo01
 * Description:
 **/
public interface UserService {

    /**
     * @Author : 徐亚远
     * @Date : 2020/2/18 20:34
     * @param username
     * @param password
     * @Description :
     */
    void login(String username, String password);
}

书写接口的实现类UserServiceImpl

package springaop07.service.impl;

import springaop07.service.UserService;

/**
 * package_name:springaop01.service.impl
 * Author:徐亚远
 * Date:2020/2/18 18:29
 * 项目名:springDemo01
 * Desription:
 **/
public class UserServlceImpl implements UserService {


    /**
     * @param password
     * @param username
     * @Author : 徐亚远
     * @Date : 2020/2/18 21:03
     * @Description :
     */

    @Override
    public void login(String username, String password) {

        System.out.println("loginUserServiceImpl登录方法执行:" + username + "    " + password);
        //异常通知时取消注释
        //int i = 10/0;
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

书写通知类

package springaop07.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * package_name:springaop07.advice
 *
 * @author:徐亚远 Date:2020/2/20 14:06
 * 项目名:springDemo01
 * Description:TODO
 * Version: 1.0
 **/

public class UserAdvice {
    private Long time;

    public Long getTime() {
        return time;
    }

    public void setTime(Long time) {
        this.time = time;
    }

    //配置前置通知方法
    public void log(JoinPoint joinPoint){
        //签名
       Signature signature = joinPoint.getSignature();
       //方法名
       String methodName = signature.getName();
       //转换为方法签名,本质上是方法签名
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        //参数
       Object [] args = joinPoint.getArgs();
       //目标类
       Object target =  joinPoint.getThis();

        System.out.println("前置通知: "+"methodName: "+methodName+" "+"args:"+Arrays.toString(args) +" "+"target: "+target);
    }
    //配置后置通知方法
    public void afterLog(JoinPoint joinPoint,Object value){

        //签名
        Signature signature = joinPoint.getSignature();
        //方法名
        String methodName = signature.getName();
        //转换为方法签名,本质上是方法签名
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        //参数
        Object [] args = joinPoint.getArgs();
        //目标类
        Object target =  joinPoint.getThis();

        System.out.println("后置通知: "+"methodName: "+methodName+" "+"args:"+Arrays.toString(args) +" "+"target: "+target);
    }

    public void throwLog(JoinPoint joinPoint,Exception ex){
        //签名
        Signature signature = joinPoint.getSignature();
        //方法名
        String methodName = signature.getName();
        //转换为方法签名,本质上是方法签名
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        //参数
        Object [] args = joinPoint.getArgs();
        //目标类
        Object target =  joinPoint.getThis();

        System.out.println("异置通知: "+"methodName: "+methodName+" "+"args:"+Arrays.toString(args) +" "+"target: "+target);
    }
    public Object aroundLog(ProceedingJoinPoint joinPoint) throws Throwable {

        System.out.println("方法执行前");
        Long startTime = System.currentTimeMillis();
         Object proceed =   joinPoint.proceed();
        Long endTime = System.currentTimeMillis();
        if (endTime-startTime > time){
            System.out.println("给管理员人发送短息:登录时间过长请优化");
        }else {
            System.out.println("方法执行后花费["+(endTime-startTime)+"]"+"ms");
        }
        return proceed;
    }

}

配置spring.xml配置文件
当实现某个通知时把该通知的注解取消,在下面的配置文件中
注意异常通知时在UserServiceImpl类中取消//int i = 10/0;这个注解

<?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">

    <!--springAop 2.x配置-->
    <!--配置目标类实例-->
    <bean id="userService" class="springaop07.service.impl.UserServlceImpl"/>

    <!--配置advice通知-->
    <bean id="userAdvice" class="springaop07.advice.UserAdvice">
        <property name="time" value="3000"/>
    </bean>
    <!--配置切入点并织入 引入 <aop:config>命名空间-->
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="us" expression="within(springaop07.service.impl.UserServlceImpl)"/>
        <!--织入配置通知-->
        <aop:aspect ref="userAdvice">
        
            <!--前置通知 将userAdvice类中的log方法织入到us对应的切入点-->
            <!--<aop:before method="log" pointcut-ref="us"/>-->
            <!--后置通知 将userAdvice类中的afterLog方法织入到us对应的切入点-->
            <!--<aop:after-returning method="afterLog" pointcut-ref="us" returning="value"/>-->
            <!--异置通知 将userAdvice类中的afterLog方法织入到us对应的切入点-->
            <!--<aop:after-throwing method="throwLog" pointcut-ref="us" throwing="ex"/>-->
            <!--环绕通知 将userAdvice类中的afterLog方法织入到us对应的切入点-->
            <aop:around method="aroundLog" pointcut-ref="us"/>
        </aop:aspect>
    </aop:config>
</beans>

环绕通知的结果如图:
在这里插入图片描述
前置通知的结果如图:
在这里插入图片描述
后置通知结果如图:
在这里插入图片描述
异常通知结果如图:
在这里插入图片描述

IT小工小徐 发布了64 篇原创文章 · 获赞 1 · 访问量 860 私信 关注

标签:joinPoint,target,后置,前置,System,Object,SpringAop,org,public
来源: https://blog.csdn.net/weixin_43311650/article/details/104426554

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有