Spring课程 Spring入门篇 7-2 Advice定义及实例

课程链接:

1    解析

1.1  通知:after和afterreturning的区别

1.2  @RunWith 是什么?

2    代码演练

2.1  注解方式配置通知的两种方式

2.2  异常通知

2.3  非异常通知

1    解析

1.1  通知:after和afterreturning的区别

a  after 后置通知相当于finally的功能,无论是否发生异常,都会执行,而返回后通知afterReturning 则在发生异常后,不再执行。

b  after 后置通知 不会有返回值,而afterReturning返回后通知,一般有返回值,  详细代码演练参考2.2

c  如果同时有after 和afterReturning,一般先执行after,后执行afterReturning     详细代码演练参考2.3

1.2  @RunWith 是什么?

@RunWith 是一个运行器 * *

@RunWith(JUnit4.class)就是指用JUnit4来运行 * *

@RunWith(Suite.class)的话就是一套测试集合 * *

@RunWith(Suite.class)的话就是一套测试集合 * *

@ContextConfiguration Spring整合JUnit4测试时,使用注解引入多个配置文件

2    代码演练

2.1  注解方式配置通知的两种方式(着重看切面类)

测试类:

package com.imooc.test.aop;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;

import com.imooc.aop.aspectj.biz.MoocBiz;
import com.imooc.test.base.UnitTestBase;

/**    @RunWith 是一个运行器 
 *     
 * @RunWith(JUnit4.class)就是指用JUnit4来运行       
 *    
 *@RunWith(Suite.class)的话就是一套测试集合
 *
 *@RunWith(Suite.class)的话就是一套测试集合                                                 
 *                                        
 *@ContextConfiguration Spring整合JUnit4测试时,使用注解引入多个配置文件                                                  
 * 
 * @author weijingli
 */
@RunWith(BlockJUnit4ClassRunner.class)
public class TestAspectJ extends UnitTestBase{

    public TestAspectJ() {
        super("classpath:spring-aop-aspectj.xml");
    }
    
    @Test
    public void testAspectJ(){
        MoocBiz mBiz = super.getbean("moocBiz");
        mBiz.save("This is Test!");
    }
    

}

配置文件:

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


<!-- 自己添加注意:
1    context:component-scan 扫描包,根据注解找到通知。         使用注解的时候,记得添加扫描包的功能
2    aop:aspectj-autoproxy 通过配置织入@Aspectj切面 -->

  <context:component-scan base-package="com.imooc.aop.aspectj"/>

  <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 <bean id="moocBiz" class="com.imooc.aop.aspectj.biz.MoocBiz"></bean>
 
</beans>

实体类:

package com.imooc.aop.aspectj.biz;

import org.springframework.stereotype.Service;

@Service
public class MoocBiz {
    /**
     * 1    为什么 用 save方法 返回 String 类型?
     * 
     * 答:为了方便After Or AfterReturning 通知  接收  返回值
     * 
     * 2     为什么接收String 参数?
     * 
     * 答:只是为了方便测试,没有任何实际意义。
     * @param arg
     * @return
     */
    public String save(String arg){
        System.out.println("MoocBiz save "+arg);
        return "Save Success!";
    }
}

切面类:

package com.imooc.aop.aspectj;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 注解切面类
 * 注:本页面主要功能是:整理各种通知的注解
 * @author weijingli
 *
 */

@Component
@Aspect
public class MoocAspect {
    
    /**
     * 该处设置切入点,主要是用来匹配目标对象类
     * 
     * 执行com.imooc.aop.aspect.biz 包下的 以Biz结尾的类的所有方法
     */
    @Pointcut("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))")
    public void pointcut(){}
    
    
    /**
     * 执行com.imooc.aop.aspect.biz 包下的所有类的  所有方法
     */
    @Pointcut("within(com.imooc.aop.aspectj.biz.*)")
    public void bizPointcut(){}
    
    
    /**
     *     前置通知   样例1
     */
    @Before("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))")
    public void before(){
        System.out.println("before1");
    }
    
    /**
     *     前置通知   样例2
     */
    @Before("pointcut()")
    public void before2(){
        System.out.println("before2");
    }
    

}

打印日志:

四月 27, 2019 4:23:00 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@53b5e629: startup date [Sat Apr 27 16:23:00 CST 2019]; root of context hierarchy
四月 27, 2019 4:23:00 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring-aop-aspectj.xml]
四月 27, 2019 4:23:00 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
信息: Overriding bean definition for bean 'moocBiz' with a different definition: replacing [Generic bean: class [com.imooc.aop.aspectj.biz.MoocBiz]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [F:xiangmu3XinFuQiangSpringddwei-dao	argetclassescomimoocaopaspectjizMoocBiz.class]] with [Generic bean: class [com.imooc.aop.aspectj.biz.MoocBiz]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [spring-aop-aspectj.xml]]
四月 27, 2019 4:23:00 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
before1
before2
MoocBiz save This is Test!
四月 27, 2019 4:23:01 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@53b5e629: startup date [Sat Apr 27 16:23:00 CST 2019]; root of context hierarchy

2.2  异常通知

实体类:

package com.imooc.aop.aspectj.biz;

import org.springframework.stereotype.Service;

@Service
public class MoocBiz {
    /**
     * 1    为什么 用 save方法 返回 String 类型?
     * 
     * 答:为了方便After Or AfterReturning 通知  接收  返回值
     * 
     * 2     为什么接收String 参数?
     * 
     * 答:只是为了方便测试,没有任何实际意义。
     * @param arg
     * @return
     */
    public String save(String arg){
        System.out.println("MoocBiz save "+arg);
        throw new RuntimeException("Save Failed!");
//        return "Save Success!";
    }
}

切面类:

package com.imooc.aop.aspectj;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 注解切面类
 * 注:本页面主要功能是:整理各种通知的注解
 * @author weijingli
 *
 */

@Component
@Aspect
public class MoocAspect {
    
    /**
     * 该处设置切入点,主要是用来匹配目标对象类
     * 
     * 执行com.imooc.aop.aspect.biz 包下的 以Biz结尾的类的所有方法
     */
    @Pointcut("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))")
    public void pointcut(){}
    
    
    /**
     * 执行com.imooc.aop.aspect.biz 包下的所有类的  所有方法
     */
    @Pointcut("within(com.imooc.aop.aspectj.biz.*)")
    public void bizPointcut(){}
    
    
    /**
     *     前置通知   样例1
     */
    @Before("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))")
    public void before(){
        System.out.println("before1");
    }
    
    /**
     * AfterReturning 执行后通知,接收  目标对象返回的值
     * @param reValue
     */
    @AfterReturning(pointcut="pointcut()",returning="reValue")
    public void afterReturning(Object reValue){
        System.out.println("AfterReturning:   "+reValue);
    }
    
    /**
     * 后置通知
     */
    @After("pointcut()")
    public void after(){
        System.out.println("after:");
    }
    
    /**
     * 异常通知:
     * 
     * 接收异常返回的信息
     */
    @AfterThrowing(pointcut="pointcut()",throwing="e")
    public void afterThrowing(RuntimeException e){
        System.out.println("AfterThrowing: "+e.getMessage());
    }
    
    
    
    /**
     *     前置通知   样例2
     */
    /*@Before("pointcut()")
    public void before2(){
        System.out.println("before2");
    }*/
    
}

打印日志:

四月 27, 2019 4:48:55 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@45a5049a: startup date [Sat Apr 27 16:48:55 CST 2019]; root of context hierarchy
四月 27, 2019 4:48:55 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring-aop-aspectj.xml]
四月 27, 2019 4:48:56 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
信息: Overriding bean definition for bean 'moocBiz' with a different definition: replacing [Generic bean: class [com.imooc.aop.aspectj.biz.MoocBiz]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [F:xiangmu3XinFuQiangSpringddwei-dao	argetclassescomimoocaopaspectjizMoocBiz.class]] with [Generic bean: class [com.imooc.aop.aspectj.biz.MoocBiz]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [spring-aop-aspectj.xml]]
四月 27, 2019 4:48:56 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
before1
MoocBiz save This is Test!
after:
AfterThrowing: Save Failed!
四月 27, 2019 4:48:56 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@45a5049a: startup date [Sat Apr 27 16:48:55 CST 2019]; root of context hierarchy

2.3  非异常通知

 切面类:

package com.imooc.aop.aspectj;

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.springframework.stereotype.Component;

/**
 * 注解切面类
 * 注:本页面主要功能是:整理各种通知的注解
 * @author weijingli
 *
 */

@Component
@Aspect
public class MoocAspect {
    
    /**
     * 该处设置切入点,主要是用来匹配目标对象类
     * 
     * 执行com.imooc.aop.aspect.biz 包下的 以Biz结尾的类的所有方法
     */
    @Pointcut("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))")
    public void pointcut(){}
    
    
    /**
     * 执行com.imooc.aop.aspect.biz 包下的所有类的  所有方法
     */
    @Pointcut("within(com.imooc.aop.aspectj.biz.*)")
    public void bizPointcut(){}
    
    
    /**
     *     前置通知   样例1
     */
    @Before("execution(* com.imooc.aop.aspectj.biz.*Biz.*(..))")
    public void before(){
        System.out.println("before1");
    }
    
    /**
     * AfterReturning 执行后通知,接收  目标对象返回的值
     * @param reValue
     */
    @AfterReturning(pointcut="pointcut()",returning="reValue")
    public void afterReturning(Object reValue){
        System.out.println("AfterReturning:   "+reValue);
    }
    
    /**
     * 后置通知  相当于java语法中的finally
     */
    @After("pointcut()")
    public void after(){
        System.out.println("after:");
    }
    
    /**
     * 异常通知:
     * 
     * 接收异常返回的信息
     */
    @AfterThrowing(pointcut="pointcut()",throwing="e")
    public void afterThrowing(RuntimeException e){
        System.out.println("AfterThrowing: "+e.getMessage());
    }
    
    /**
     * 环绕通知:
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("around 1");
        Object obj = pjp.proceed();
        System.out.println("around 2");
        System.out.println("around :"+obj);
        return obj;
    }
    
    
    /**
     *     前置通知   样例2
     */
    /*@Before("pointcut()")
    public void before2(){
        System.out.println("before2");
    }*/
  

}

打印日志:

四月 28, 2019 6:56:52 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5512ce48: startup date [Sun Apr 28 06:56:52 CST 2019]; root of context hierarchy
四月 28, 2019 6:56:52 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring-aop-aspectj.xml]
四月 28, 2019 6:56:52 上午 org.springframework.beans.factory.support.DefaultListableBeanFactory registerBeanDefinition
信息: Overriding bean definition for bean 'moocBiz' with a different definition: replacing [Generic bean: class [com.imooc.aop.aspectj.biz.MoocBiz]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [F:xiangmu3XinFuQiangSpringddwei-dao	argetclassescomimoocaopaspectjizMoocBiz.class]] with [Generic bean: class [com.imooc.aop.aspectj.biz.MoocBiz]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [spring-aop-aspectj.xml]]
四月 28, 2019 6:56:52 上午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring

around 1

before1

MoocBiz save This is Test!

around 2

around Save Success!

after:

AfterReturning:   Save Success!

四月 28, 2019 6:56:53 上午 org.springframework.context.support.ClassPathXmlApplicationContext doClose

信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@5512ce48: startup date [Sun Apr 28 06:56:52 CST 2019]; root of context hierarchy
原文地址:https://www.cnblogs.com/1446358788-qq/p/10778515.html