课程链接:

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. [Flex] 组件Tree系列 —— 利用firstVisibleItem属性,设置或取得第一个显示节点

    mxml: <?xml version="1.0" encoding="utf-8"?> <!--功能描述: 利用firstVisibleIt ...

  2. python3入门之集合set

    之前介绍python的数据结构时,没有介绍set(集合)现在在这里稍微介绍下: set原理 Python 还 包 含 了 一 个 数 据 类 型-- set ( 集 合 ) . 集 合 是 一 个 无 ...

  3. 【BZOJ1296】[SCOI2009]粉刷匠 (DP+背包)

    [SCOI2009]粉刷匠 题目描述 \(windy\)有 \(N\) 条木板需要被粉刷. 每条木板被分为 \(M\) 个格子. 每个格子要被刷成红色或蓝色. \(windy\)每次粉刷,只能选择一条 ...

  4. requests库的使用

     requests库的使用 pip快速安装 pip install requests 请求方法 每一个请求方法都有一个对应的API,比如GET请求就可以使用get()方法: import reques ...

  5. telent三种认证及vlan简单划分

    实验一 telent三种认证方式登录 实验拓扑图如下: 操作过程: 1.认证模式为none R1操作:       1.system-view进入系统试图2.telnet server enable开 ...

  6. Owin WebAPI上传文件

    Owin是微软出了几年的东东了,一直没时间学习.大概了解了下,是一个脱离IIS环境,快速搭建WebAPI服务的东西. 刚好想尝试下尽量脱离IIS创建简单快捷配置的项目,就是用了Nginx+Owin的模 ...

  7. SqlServer索引优化 查看碎片情况

    本文引自 DBCC DBREINDEX重建索引提高SQL Server性能 查看碎片情况使用  dbcc showcontig 函数来进行 代码: --改成当前库 use DB_Name --创建变量 ...

  8. windows 下创建 sqlite 数据库

    说明:windows 下执行创建 sqlite 数据库命令后数据库文件不会马上生成,需要创建表以后才会生成. 1.将 sqlite3.exe 文件放在任何位置(如放在 d:\tools )2.在 CM ...

  9. Robot Framework的安装、更新与卸载

    Robot Framework的安装.更新与卸载 一,安装RF前的准备 一般就三种执行环境 Python, Jython (JVM) 和 IronPython (.NET): 安装python: #T ...

  10. 使用spring遇到问题 事物不提交和更新失败

    1 使用学习使用spring mvc进行前端代码编写,发现提交修改没发sql语句 测试dao层又没问题 解决: 原来是spring配置文件,事物管理 绑定到了dao层.测试界面前端应该绑定到servi ...