课程链接:

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扩展的更多相关文章

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

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

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

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

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

    1 解析 1.1 通知:after和afterreturning的区别 1.2 @RunWith 是什么? 2 代码演练 2.1 注解方式配置通知的两种方式 2.2 异常通知 2.3 非异常通知 1 ...

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

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

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

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

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

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

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

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

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

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

  9. Spring课程 Spring入门篇 5-2 配置切面aspect

    本节主要讲了在xml中配置切面的demo 1 解析 1.1 配置切面xml 1.2 配置切面xml 1.3 问:什么是动态代理? 2 代码演练 2.1 配置切面xml 1 解析 1.1 配置切面xml ...

随机推荐

  1. 120、Java中String类之实现首字母大写

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  2. 五 Mybatis一对一关联查询的两种方式(基于resultType&基于resultMap)

    关联查询: 一个用户对应多个订单,一个订单只有一个用户 订单关联用户:两种方式 一:基于resultTYpe,一个与表关系一样的pojo实现 主表订单,从表用户 首先要有一个与关联查询表关系一样的po ...

  3. CXL联盟正式成立:成员均是行业巨头

    导读 今天,阿里巴巴.思科.戴尔EMC.Facebook.Google.HPE.华为.Intel.微软(按英文首字母排序)联合宣布,CXL联盟(Compute Express Link Consort ...

  4. save the transient instance before flushing错误解决办法

    错误原因: new了一个新对象,在未保存之前将它保存进了一个新new的对象(也即不是持久态). 解决办法: 在保存或更新之前把这个对象查出来(这样就是一个持久态) <set name=" ...

  5. P1091合唱队形(LIS问题)

    题目描述(题目链接:https://www.luogu.org/problem/P1091) NN位同学站成一排,音乐老师要请其中的(N-KN−K)位同学出列,使得剩下的KK位同学排成合唱队形. 合唱 ...

  6. 【rabbitmq】Queueingconsumer被废止后老代码如何做的解决方案

    amqp-client 3.x之前的rabbitmq版本有个消费者的写法是借助于Queueingconsumer的: QueueingConsumer consumer = new QueueingC ...

  7. 生成MyEclipse6.5&7.5&8.5 注册机源码

    分类: java技术2010-09-30 21:46 26638人阅读 评论(6) 收藏 举报 myeclipsejavastringimportinputbyte 生成MyEclipse8.5注册码 ...

  8. sqlserver数据库查询

    帮助类 using System; using System.Collections.Generic; using System.Data; using System.Data.SqlClient; ...

  9. ES6中 ,var,let和const的区别

    var的特点 没有代码块的概念,全局范围内都有效 存在“变量提升”现象,即变量可以在声明之前使用,值为undefined let的特点 声明的变量仅在块级作用域内有效,存在了代码块的概念 不存在“变量 ...

  10. 51nod 1441:士兵的数字游戏

    1441 士兵的数字游戏 题目来源: CodeForces 基准时间限制:4 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  取消关注 两个士兵正在玩一个游戏,游戏开始的时 ...