课程链接:

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. ArchLinux "error: required key missing from keyring"

    downloading required keys... error: key "C847B6AEB0544167" could not be looked up remotely ...

  2. thinkphp3.2.3----图片上传并生成缩率图

    public function uploadify(){ if(!IS_POST){ $this->error('非法!'); } $upload = $this->_upload(); ...

  3. window.onload和JQuery中$(function(){})的区别即其实现原理

    一.区别 window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行. 在Jquery中$(function(){ })和$(document).ready(function(){ ...

  4. 提交app时候遇到IDFA警告

    1.最近提交app时候遇到如下问题,解决方案: Everything has come to its usual state now. Simply upload your binary as you ...

  5. 搭建maven环境——nexus

    第一步:部署maven环境和jdk环境 jdk直接用openjdk1. :yum -y install java--openjdk maven环境 wget http://mirror.rise.ph ...

  6. python全栈开发_day3_数据类型,输入输出及运算符

    一:常见数据类型 1)int整型 例:age=1 整型常用于年龄,账号等 2)float浮点型 例:salary=5.1 浮点型常用于薪水,身高,体重等 3)str字符串类型 例:name=“chen ...

  7. Flutter Dialog 屏蔽返回键

    使用 WillPopScope + Future.value(false); 屏蔽返回键.代码如下: showDialog<Null>( context: context, // Buil ...

  8. 第九次 Scrum Meeting

    第九次 Scrum Meeting 写在前面 会议时间 会议时长 会议地点 2019/4/14 19:00 60min 新主楼F座2F 附Github仓库:WEDO 例会照片 工作情况总结(4.14) ...

  9. CentOS&.NET Core初试-3-Nginx的安装和配置

    系列目录 CentOS的安装和网卡的配置 安装.NET Core SDK和发布网站 Nginx的安装和配置 安装守护服务(Supervisor) Nginx简介   Nginx是一个免费的,开源的,高 ...

  10. JDK,JRE,JVM的基础理解

    1.JVM -- java virtual machine JVM就是我们常说的java虚拟机,它是整个java实现跨平台的 最核心的部分,所有的java程序会首先被编译为.class的类文件,这种类 ...