Spring课程 Spring入门篇 7-3 advice扩展
1 解析
1.1 advice中aspect 切面传参
1.2 通知参数名称——argNames属性, 参数为 JoinPoint、ProceedingJoinPoint、JoinPointStaticPart时,可以忽略argNames属性
1.3 其余不重要的部分
2 代码演练
2.1 前置通知@before给advice传递参数
2.1 前置通知@before传递类参数
1 解析
1.1 advice中aspect 切面传参
String传参和类传参参照2.1和2.2
泛型传参

1.2 通知参数名称——argNames属性, 参数为 JoinPoint、ProceedingJoinPoint、JoinPointStaticPart时,可以忽略argNames属性

1.3 其余不重要的部分

Introductions
·允许一个切面声明一个通知对象实现指定接口,并且提供了一个接口实现类来代表这些对象
·introduction使用@DeclareParents进行注解,这个注解用来定义匹配的类型拥有一个新的parent

2 代码演练
2.1 前置通知@before给advice传递String参数
切面类:
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;
} /**
* 前置通知 带参数
*/
@Before("pointcut()&&args(arg)")
public void beforeWithParam(String arg){
System.out.println("beforeWithParam:"+arg);
} /**
* 前置通知 样例2
*/
/*@Before("pointcut()")
public void before2(){
System.out.println("before2");
}*/ }
实体类:
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!";
}
}
配置文件:
<?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.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!");
} }
打印日志:
五月 02, 2019 2:28:44 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7fe219e7: startup date [Thu May 02 14:28:44 CST 2019]; root of context hierarchy
五月 02, 2019 2:28:44 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring-aop-aspectj.xml]
五月 02, 2019 2:28:45 下午 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]]
五月 02, 2019 2:28:45 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
around 1
before1
beforeWithParam:This is Test!
MoocBiz save This is Test!
around 2
around :Save Success!
after:
AfterReturning: Save Success!
五月 02, 2019 2:28:45 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@7fe219e7: startup date [Thu May 02 14:28:44 CST 2019]; root of context hierarchy
2.2 前置通知@before传递类参数
注解类:
package com.imooc.aop.aspectj; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 1 关于RetentionPolicy
* 1.1 RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
* 1.2 RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
* 1.3 RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
* SOURCE < CLASS < RUNTIME
*
*
* 2 关于ElementType.METHOD
* 2.1
* 表示注解MoocMethod能用来修饰类中的Method
*
* @author weijingli
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MoocMethod { String value();
}
切面类:
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;
} /**
* 前置通知 带参数
*/
@Before("pointcut()&&args(arg)")
public void beforeWithParam(String arg){
System.out.println("beforeWithParam:"+arg);
} /**
* 前置通知 传入类
*/
@Before("pointcut()&&@annotation(moocMethod)")
public void beforeWithAnnotation(MoocMethod moocMethod){
System.out.println("beforeWithAnnotation,"+moocMethod.value());
} /**
* 前置通知 样例2
*/
/*@Before("pointcut()")
public void before2(){
System.out.println("before2");
}*/ }
实体类:
package com.imooc.aop.aspectj.biz; import org.springframework.stereotype.Service; import com.imooc.aop.aspectj.MoocMethod; @Service
public class MoocBiz {
/**
* 1 为什么 用 save方法 返回 String 类型?
*
* 答:为了方便After Or AfterReturning 通知 接收 返回值
*
* 2 为什么接收String 参数?
*
* 答:只是为了方便测试,没有任何实际意义。
* @param arg
* @return
*/
@MoocMethod("MoocBiz save MoocMethod")
public String save(String arg){
System.out.println("MoocBiz save "+arg);
// throw new RuntimeException("Save Failed!");
return "Save Success!";
}
}
测试类:
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配置:
<?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>
打印日志:
五月 02, 2019 3:45:28 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3f64fffc: startup date [Thu May 02 15:45:28 CST 2019]; root of context hierarchy
五月 02, 2019 3:45:28 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring-aop-aspectj.xml]
五月 02, 2019 3:45:28 下午 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]]
五月 02, 2019 3:45:28 下午 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor <init>
信息: JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
around 1
before1
beforeWithAnnotation,MoocBiz save MoocMethod
beforeWithParam:This is Test!
MoocBiz save This is Test!
around 2
around :Save Success!
after:
AfterReturning: Save Success!
五月 02, 2019 3:45:29 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@3f64fffc: startup date [Thu May 02 15:45:28 CST 2019]; root of context hierarchy
Spring课程 Spring入门篇 7-3 advice扩展的更多相关文章
- Spring Boot -01- 快速入门篇(图文教程)
Spring Boot -01- 快速入门篇(图文教程) 今天开始不断整理 Spring Boot 2.0 版本学习笔记,大家可以在博客看到我的笔记,然后大家想看视频课程也可以到[慕课网]手机 app ...
- Spring实践系列-入门篇(一)
本文主要介绍了在本地搭建并运行一个Spring应用,演示了Spring依赖注入的特性 1 环境搭建 1.1 Maven依赖 目前只用到依赖注入的功能,故以下三个包已满足使用. <properti ...
- Spring课程 Spring入门篇 7-2 Advice定义及实例
1 解析 1.1 通知:after和afterreturning的区别 1.2 @RunWith 是什么? 2 代码演练 2.1 注解方式配置通知的两种方式 2.2 异常通知 2.3 非异常通知 1 ...
- Spring课程 Spring入门篇 6-1 Spring AOP API的PointCut、advice的概念及应用
本节主要是模拟spring aop 的过程. 实现spring aop的过程 这一节老师虽然说是以后在工作中不常用这些api,实际上了解还是有好处的, 我们可以从中模拟一下spring aop的过程. ...
- Spring课程 Spring入门篇 5-4 advice应用(上)
1 解析 1.1 通知执行顺序 2 代码演练 1 解析 1.1 通知执行顺序 aop执行方式为:前置通知==>所要增强的方法==>后置通知==>最终通知 在出现异常时会进行:前置通知 ...
- Spring课程 Spring入门篇 5-5 advice应用(下)
2 代码演练 2.1 环绕通知(不带参数) 2.2 环绕通知(带参数) 2 代码演练 2.1 环绕通知(不带参数) 实体类: package com.imooc.aop.schema.advice.b ...
- Spring课程 Spring入门篇 6-2 ProxyFactoryBean及相关内容(上)
1 解析 1.1 类的方式实现各种通知需要实现的接口 1.2 创建Spring aop代理的优点及方法 1.3 代理控制切入点和通知的顺序的代码实现(具体完全实现,见代码2.1) 1.4 代理方式选择 ...
- Spring课程 Spring入门篇 6-3 ProxyFactoryBean及相关内容(下)
1 解析 1.1 使用global advisors demo 1.2 jdk代理和cglib代理的选择 1.3 如何强制使用CGLIB实现AOP? 1.4 JDK动态代理和CGLIB字节码生成的区别 ...
- Spring课程 Spring入门篇 5-2 配置切面aspect
本节主要讲了在xml中配置切面的demo 1 解析 1.1 配置切面xml 1.2 配置切面xml 1.3 问:什么是动态代理? 2 代码演练 2.1 配置切面xml 1 解析 1.1 配置切面xml ...
随机推荐
- 写给想要入门python或者正在入门python的小朋友们
写在前面: 最近好像python挺火,虽然我也在天天写python,但是python毕竟是动态语言,就拿常被人吐槽的java来说,python绝大不多数地方是不如java的.python只能是你的一个 ...
- CSS - 去除图片img底侧空白缝隙
1. 图片底部有空隙 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- 大部分政府网站U-mail存在直接拿shell漏洞
大部分网站政府网站U-mail存在直接拿shell漏洞加入webmail/userapply.php?execadd=333&DomainID=111直接爆出物理地址 然后将 aa' unio ...
- redis学习笔记-04:redis五大数据结构类型
redis的命令大全网站:http://redisdoc.com/ 一.redis五大数据类型 1.String(字符串).Hash(哈希,类似Java里的Map).List(列表).Set(集合)和 ...
- Cookie存储在哪里
内存是临时存储,关机后信息就没了.硬盘是长久存储,不删除就一直在.内存容量决定你电脑能同时运行的程序多少,硬盘容量决定你电脑能存放多少东西. 好比内存是手,硬盘是口袋,东西可以临时放在手里,可是口袋才 ...
- 103、Java中String类之compareTo()方法
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- UDP打洞实验
依云 posted @ 2 年前 in 网络 with tags python 网络 socat UDP , 7095 阅读 本文来自依云's Blog,转载请注明. 两台没有外网 IP.在 NAT ...
- Android按返回键退出程序
既然想实现 按两次返回键 退出程序 有两个关键词 一个是 “返回键”,再一个是“退出程序” )先说“退出” 退出相信大家都会 finish(); System.exit(); 为了确保不出现问题,两种 ...
- jquery解析
OutOfMemory.CN β 聚客 代码 专栏 教程 Maven Gitter 标签 登录注册 好书:重构 改善既有代码的设计[京东 亚马逊] | 敏捷软件开发原则.模式与实践[京东 亚 ...
- python-python基础2
本章内容: 1.列表.元组 2.字典 3.集合 4.文件操作 5.字符编码与转码 一.列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 names= ...