首页 > 其他分享 >Spring配置切面(AOP)

Spring配置切面(AOP)

时间:2023-02-28 12:55:30浏览次数:48  
标签:Spring void System 通知 切面 AOP println public out

AOP,面向接口的编程,实际上是代理模式的实现。

参考:代理模式(Proxy)

 

 


 

一、使用Scheme-based方式配置

需要实现接口重写指定方法,来确定通知所在位置。

(一)、前置通知和后置通知

切点类:

public class Client {
    public void sayHi(){
        System.out.println("Client.sayHi");
    }
}

通知类:

  前置通知实现接口:MethodBeforeAdvice,在实现方法中可获取方法对象,参数数组,调用对象

  后置通知实现接口:AfterReturningAdvice,在实现方法中可获取方法对象,参数数组,调用对象,返回值

public class TestBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("执行前置通知");
    }
}

xml配置:

   <!--切点类-->
   <bean class="com.lurenjia.test.Client" id="client"></bean>
   <!--前置通知对象-->
    <bean id="mybefore" class="com.lurenjia.advice.TestBeforeAdvice"></bean>
    <!--后置通知对象-->
    <bean id="after" class="com.lurenjia.advice.TestAfterAdvice"></bean>
    <!--配置一个aop-->
    <aop:config>
        <!--切点-->
        <aop:pointcut id="mypoint" expression="execution(* com.lurenjia.test.Client.sayHi())"/>
        <!--配置一个前置通知-->
        <aop:advisor advice-ref="mybefore" pointcut-ref="mypoint"></aop:advisor>
        <!--配置一个后置通知-->
        <aop:advisor advice-ref="after" pointcut-ref="mypoint"></aop:advisor>
    </aop:config>

(二)、异常通知

  异常通知类的实现方法不为接口提供,是spring文档提供的。(奇奇怪怪)

切点类:

  一般在service中都采取抛出异常,从而使得spring进行捕获异常进行事务处理。

public class Client {
    public void doSomething2() throws Exception{
        int a = 5/0;
    }
}

通知类:

  自行指定方法名,可在参数中获取方法对象,参数对象,执行对象,异常对象,(或者只获取异常对象)

public class TestThrowAdvice implements ThrowsAdvice {
    /**
     * 指定此方法名才能被调用*/
    public void afterThrowing(Method method,Object[] args,Object target,Exception e){
        System.out.println("获取到发生异常的方法:"+method.getName());
        System.out.println("获取到参数:"+args);
        System.out.println("获取到调用对象:"+target);
        System.out.println("获取到异常:"+e.getMessage());
    }
}

xml配置:

   <!--切点类-->
   <bean class="com.lurenjia.test.Client" id="client"></bean>
    <!--异常通知对象-->
    <bean class="com.lurenjia.advice.TestThrowAdvice" id="throw"></bean>
    <!--配置一个aop-->
    <aop:config>
        <!--切点-->
        <aop:pointcut id="myponint2" expression="execution(* com.lurenjia.test.Client.doSomething2())"/>
        <!--配置一个异常通知-->
        <aop:advisor advice-ref="throw" pointcut-ref="myponint2"></aop:advisor>
    </aop:config>

(三)、环绕通知

  在方法前后都织入通知。

切点类:

public class Client {
    public void sayHi(){
        System.out.println("Client.sayHi");
    }
}

通知类:

public class TestArround implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        //前置处理
        System.out.println("前置处理了");

        //执行方法
        Object proceed = methodInvocation.proceed();

        //后置处理
        System.out.println("后置处理了");
        //返回结果
        return proceed;
    }
}

xml配置:

   <!--切点类-->
   <bean class="com.lurenjia.test.Client" id="client"></bean>
   <!--环绕通知对象-->
    <bean id="arround" class="com.lurenjia.advice.TestArround"></bean>
    <aop:config>
        <!--切点-->
        <aop:pointcut id="point1" expression="execution(* com.lurenjia.test.Client.sayHi())"/>
        <!--配置一个环绕通知-->
        <aop:advisor advice-ref="arround" pointcut-ref="point1"></aop:advisor>
    </aop:config>

二、使用AspectJ方式配置

不需要实现接口,完全自定义方法,所以需要在xml中配置方法位置。

(一)、配置通知

切点类:

public class Client {
    public void sayHi() throws Exception{
        //int i = 7/0;
        System.out.println("执行方法");
    }
}

通知类:

public class TestAspectjAdvice {

    public void myBefore(){
        System.out.println("before:前置通知!");
    }

    public void myAfter(){
        System.out.println("after:finally后置通知!");
    }

    public void myFnalliy(){
        System.out.println("after-returning:后置通知!");
    }

    public void myThrow(){
        System.out.println("after-throwing:异常通知!");
    }
public Object myArround(ProceedingJoinPoint joinPoint) throws Throwable { //前置操作 System.out.println("around:前置操作"); //执行方法 Object result = joinPoint.proceed(); //后置操作 System.out.println("around:后置操作"); //返回值返回 return result; } }

xml配置:

    <!--切点类-->
    <bean class="com.lurenjia.test.Client" id="client"></bean>
    <!--通知类-->
    <bean class="com.lurenjia.advice.TestAspectjAdvice" id="advice"></bean>
    <!--配置一个切面-->
    <aop:config>
        <!--使用的通知类-->
        <aop:aspect ref="advice">
            <!--切点方法-->
            <aop:pointcut id="point1" expression="execution(* com.lurenjia.test.Client.sayHi())"/>
            <!--前置通知-->
            <aop:before method="myBefore" pointcut-ref="point1"></aop:before>
            <!--后置通知-->
            <aop:after method="myAfter" pointcut-ref="point1"></aop:after>
            <!--finally通知-->
            <aop:after-returning method="myFnalliy" pointcut-ref="point1"></aop:after-returning>
            <!--异常通知-->
            <aop:after-throwing method="myThrow" pointcut-ref="point1"></aop:after-throwing>
            <!--环绕通知-->
            <aop:around method="myArround" pointcut-ref="point1"></aop:around>
        </aop:aspect>
    </aop:config>

(二)、获取参数

切点类:

public class Client {
    public void sayHi(String name,int age) throws Exception{
        System.out.println("执行方法");
    }
}

通知类:

public class TestAspectjAdvice {

    public void myBefore(String name,int age){
        System.out.println("before:前置通知!");
        System.out.println("获取到参数:"+name+"-"+age);
    }
}

xml配置:

    <!--切点类-->
    <bean class="com.lurenjia.test.Client" id="client"></bean>
    <!--通知类-->
    <bean class="com.lurenjia.advice.TestAspectjAdvice" id="advice"></bean>
    <!--配置一个切面-->
    <aop:config>
        <!--使用的通知类-->
        <aop:aspect ref="advice">
            <!--切点方法,声明参数类型和名称-->
            <aop:pointcut id="point1"
                          expression="execution(* com.lurenjia.test.Client.sayHi(String,int)) and args(name,age)"/>

            <!--前置通知,配置参数名必须与上面声明的一样-->
            <aop:before method="myBefore" pointcut-ref="point1" arg-names="name,age"></aop:before>
        </aop:aspect>
    </aop:config>

 

标签:Spring,void,System,通知,切面,AOP,println,public,out
From: https://www.cnblogs.com/lurenjia-bky/p/17163616.html

相关文章

  • spring redis 工具类
    /***springredis工具类**@authorhanzj**///@SuppressWarnings(value={"unchecked","rawtypes"})@ServicepublicclassRedisForLbCache{@Autowiredp......
  • 深入理解Spring的Bean定义对象BeanDefinition-面试重点
    Spring注解这篇文章中讲到了Spring的组件,组件加载到Spring容器中也就是Spring容器中的Bean对象,想要更深理解Spring中的Bean对象,那对这个BeanDefinition一定要有深入的了解,......
  • SpringBoot全局异常封装:AOP增强
    api请求错误返回json,页面请求错误跳转报错页面:自动装配、异常通知两个方法Java异常类错误无法避免,通常由于系统原因造成。如IOError,注意不是IOException,原因可能是......
  • spring 相关总结
    一、 spring-boot-starter-data-jpa spring-boot-starter-jdbc区别参考1: spring-boot-starter-data-jpa与spring-boot-starter-jdbcspring-boot-starter-data-jpa......
  • 【spring笔记】Spring整合Mybaties
    官方文档:http://mybatis.org/spring/zh/sqlsession.html1、实现方式1核心思想:利用Spring配置依赖注入创建sqlSessionFactory和sqlSession实例需要的包如下:1.1、编......
  • 【spring笔记】Spring声明事务
    前情提要:事物在Mysql数据库中已经学过,具有ACID的特性1、Spring事物管理分为两类:声明式事物:AOP编程式事物:需要在代码中,进行事物的管理编程式事物还是没有AOP的统一处理......
  • 【spring笔记】Mybaties入门
    1、官方文档https://mybatis.org/mybatis-3/zh/getting-started.html2、搭建一个Mybatis实例2.1首先看配置文件mybatis-config.xml这里面包括获取数据库连接实例的数......
  • springboot处理乱码问题原理
    我们在用spring-springmvc时,需要配置一个过滤器 CharacterEncodingFilterCharacterEncodingFilterfilter=newOrderedCharacterEncodingFilter();filter.setEncodin......
  • 学习springCloud的配置之Swagger的配置
    文章来源于:https://www.bbsmax.com/A/1O5E3VP4z7/本文仅做学习记录用途SpringCloud配置中心采用数据库存储配置内容转自:SpringCloudConfig采用数据库存储配置内容【......
  • springboot集成easyexcel(阿里)
    poi比较占用内存。easyexcel性能优化不少,值得一看。pom.xml中添加:<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.6</......