课程链接:

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:\xiangmu3\Xin\FuQiang\Spring\ddwei-dao\target\classes\com\imooc\aop\aspectj\biz\MoocBiz.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:\xiangmu3\Xin\FuQiang\Spring\ddwei-dao\target\classes\com\imooc\aop\aspectj\biz\MoocBiz.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:\xiangmu3\Xin\FuQiang\Spring\ddwei-dao\target\classes\com\imooc\aop\aspectj\biz\MoocBiz.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

Spring课程 Spring入门篇 7-2 Advice定义及实例的更多相关文章

  1. Spring Boot -01- 快速入门篇(图文教程)

    Spring Boot -01- 快速入门篇(图文教程) 今天开始不断整理 Spring Boot 2.0 版本学习笔记,大家可以在博客看到我的笔记,然后大家想看视频课程也可以到[慕课网]手机 app ...

  2. Spring实践系列-入门篇(一)

    本文主要介绍了在本地搭建并运行一个Spring应用,演示了Spring依赖注入的特性 1 环境搭建 1.1 Maven依赖 目前只用到依赖注入的功能,故以下三个包已满足使用. <properti ...

  3. 【SSRS】入门篇(三) -- 为报表定义数据集

    原文:[SSRS]入门篇(三) -- 为报表定义数据集 通过前两篇文件 [SSRS]入门篇(一) -- 创建SSRS项目 和 [SSRS]入门篇(二) -- 建立数据源 后, 我们建立了一个SSRS项 ...

  4. Spring课程 Spring入门篇 7-3 advice扩展

    课程链接: 1 解析 1.1 advice中aspect 切面传参 1.2 通知参数名称——argNames属性, 参数为 JoinPoint.ProceedingJoinPoint.JoinPoin ...

  5. Spring课程 Spring入门篇 6-1 Spring AOP API的PointCut、advice的概念及应用

    本节主要是模拟spring aop 的过程. 实现spring aop的过程 这一节老师虽然说是以后在工作中不常用这些api,实际上了解还是有好处的, 我们可以从中模拟一下spring aop的过程. ...

  6. Spring课程 Spring入门篇 5-4 advice应用(上)

    1 解析 1.1 通知执行顺序 2 代码演练 1 解析 1.1 通知执行顺序 aop执行方式为:前置通知==>所要增强的方法==>后置通知==>最终通知 在出现异常时会进行:前置通知 ...

  7. Spring课程 Spring入门篇 5-5 advice应用(下)

    2 代码演练 2.1 环绕通知(不带参数) 2.2 环绕通知(带参数) 2 代码演练 2.1 环绕通知(不带参数) 实体类: package com.imooc.aop.schema.advice.b ...

  8. Spring课程 Spring入门篇 6-2 ProxyFactoryBean及相关内容(上)

    1 解析 1.1 类的方式实现各种通知需要实现的接口 1.2 创建Spring aop代理的优点及方法 1.3 代理控制切入点和通知的顺序的代码实现(具体完全实现,见代码2.1) 1.4 代理方式选择 ...

  9. Spring课程 Spring入门篇 6-3 ProxyFactoryBean及相关内容(下)

    1 解析 1.1 使用global advisors demo 1.2 jdk代理和cglib代理的选择 1.3 如何强制使用CGLIB实现AOP? 1.4 JDK动态代理和CGLIB字节码生成的区别 ...

随机推荐

  1. 实现反转的方法(reverse)

    1.最简单的方法: public static String reverse1(String str) { return new StringBuffer(str).reverse().toStrin ...

  2. flask内置函数 send_static_file(filename)

    内部使用的函数将静态文件从静态文件夹发送到浏览器. current_app.send_static_file(filename)

  3. python爬虫urllib库使用

    urllib包括以下四个模块: 1.request:基本的HTTP请求模块,可以用来模拟发送请求.就像在浏览器里输入网址然后回车一样,只需要给库方法传入URL以及额外的参数,就可以模拟实现这个过程. ...

  4. 匈牙利算法、KM算法

    PS:其实不用理解透增广路,交替路,网上有对代码的形象解释,看懂也能做题,下面我尽量把原理说清楚 基本概念 (部分来源.部分来源) 二分图: 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相 ...

  5. python函数参数类型及其顺序

    根据inspect模块官文文档中关于函数参数类型的相关说明,python函数参数共有五种类型,按顺序分别为:POSITIONAL_ONLY.POSITIONAL_OR_KEYWORD.VAR_POSI ...

  6. UML-4-初始不是需求阶段

    1.初始阶段到底做什么? 确定项目外包还是自研.成本多少. 系统边界 关键的10%的用例.非功能性需求分析,业务案例创建 开发环境准备 而需求分析是在细化阶段进行的. 2.初始阶段(或细化阶段早期)应 ...

  7. Jmeter使用指南----压力测试工具

    来源: https://blog.csdn.net/u012111923/article/details/80705141 https://www.cnblogs.com/st-leslie/p/51 ...

  8. c#操作mysql

    using System; using MySql.Data; using MySql.Data.MySqlClient; using System.Data; using System.Linq; ...

  9. 关于z-index问题

    关于z-inde,这个网址还是对我受益匪浅的,https://www.cnblogs.com/bigboyLin/p/4621335.html z-index 起作用得有一个前提: 就是和定位一起用, ...

  10. ORACLE MERGE INTO UPDATE DELETE 用法

    ORACLE MERGE INTO UPDATE DELETE 用法 使用该MERGE语句从一个或多个源中选择行以进行更新或插入表或视图.您可以指定条件以确定是更新还是插入目标表或视图. 此语句是组合 ...