Spring学习(21)--- AOP之Advice应用(上)
| 前置通知(Before advice) | 在某个连接点(join point)之前执行的通知,但不能阻止连接点前的执行(除非它抛出异常) |
| 返回后通知(After returning advice) | 在某个连接点(join point)正常完成后执行的通知 |
| 抛出异常后通知(After throwing advice) | 在方法抛出异常退出时执行的通知 |
| 后通知(After(finally) advice) | 当某个连接点退出的时候执行的通知(无论是正常返回还是异常退出) |
| 环绕通知(Around advice) | 包围一个连接点(join point)的通知 |
导入需要的包:aspectjweaver.jar、aopalliance-1.0.jar
(一)Before Advice
例子:
新建两个类:
package com.aop.schema;
/**
*
* 切面类
*
*/
public class MyAspect { public void before(){
System.out.println("MyAspect.before");
}
}
package com.aop.schema;
/**
*
* 业务类
*
*/
public class ApsectBiz { public void biz(){
System.out.println("ApsectBiz.biz");
}
}
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-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <bean id="myAspect" class="com.aop.schema.MyAspect"></bean> <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean> <aop:config>
<aop:aspect id="myAspectAOP" ref="myAspect">
<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
<aop:before method="before" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config> </beans>
单元测试:
package com.aop.schema; import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class UnitTest { @Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-aop.xml");
ApsectBiz biz = (ApsectBiz)context.getBean("apsectBiz");
biz.biz();
}
}
结果:
七月 09, 2015 10:30:24 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:30:24 CST 2015]; root of context hierarchy
七月 09, 2015 10:30:24 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
MyAspect.before
ApsectBiz.biz
PS:ApsectBiz.biz是业务方法,在它之前,执行了前置通知MyAspect.before,符合想要的结果
(二)After returning advice
例子:
修改一下切面类MyAspect(添加afterreturning方法):
package com.aop.schema;
/**
*
* 切面类
*
*/
public class MyAspect { public void before(){
System.out.println("MyAspect.before");
} public void afterreturning(){
System.out.println("MyAspect.afterreturning");
}
}
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-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <bean id="myAspect" class="com.aop.schema.MyAspect"></bean> <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean> <aop:config>
<aop:aspect id="myAspectAOP" ref="myAspect">
<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
<aop:before method="before" pointcut-ref="myPointcut"/>
<aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config> </beans>
单元测试同上:
结果:
七月 09, 2015 10:38:41 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:38:41 CST 2015]; root of context hierarchy
七月 09, 2015 10:38:41 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
MyAspect.before
ApsectBiz.biz
MyAspect.afterreturning
(三)After throwing advice
说明:使用throwing属性来指定可被传递的异常的参数名称
例子:
修改一下切面类MyAspect(添加afterthrowing方法):
package com.aop.schema;
/**
*
* 切面类
*
*/
public class MyAspect { public void before(){
System.out.println("MyAspect.before");
} public void afterreturning(){
System.out.println("MyAspect.afterreturning");
} public void afterthrowing(){
System.out.println("MyAspect.afterthrowing");
}
}
修改业务类ApsectBiz(抛出一个异常):
package com.aop.schema; /**
*
* 业务类
*
*/
public class ApsectBiz { public void biz(){
System.out.println("ApsectBiz.biz");
throw new RuntimeException(); //故意抛出异常
}
}
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-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <bean id="myAspect" class="com.aop.schema.MyAspect"></bean> <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean> <aop:config>
<aop:aspect id="myAspectAOP" ref="myAspect">
<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
<aop:before method="before" pointcut-ref="myPointcut"/>
<aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>
<aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config> </beans>
单元测试同上:
测试结果:
七月 09, 2015 10:47:46 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:47:46 CST 2015]; root of context hierarchy
七月 09, 2015 10:47:46 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
MyAspect.before
ApsectBiz.biz
MyAspect.afterthrowing
PS:有没有发现有什么问题? MyAspect.afterreturning没有了,biz()中抛出异常,biz()方法没有正常返回,所以MyAspect.afterreturning没有了。
(四)After(finally) advice
修改一下切面类MyAspect(添加after方法):
package com.aop.schema;
/**
*
* 切面类
*
*/
public class MyAspect { public void before(){
System.out.println("MyAspect.before");
} public void afterreturning(){
System.out.println("MyAspect.afterreturning");
} public void afterthrowing(){
System.out.println("MyAspect.afterthrowing");
} public void after(){
System.out.println("MyAspect.after");
}
}
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-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <bean id="myAspect" class="com.aop.schema.MyAspect"></bean> <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean> <aop:config>
<aop:aspect id="myAspectAOP" ref="myAspect">
<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
<aop:before method="before" pointcut-ref="myPointcut"/>
<aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>
<aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>
<aop:after method="after" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config> </beans>
单元测试同上:
结果:
七月 09, 2015 10:56:10 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:56:10 CST 2015]; root of context hierarchy
七月 09, 2015 10:56:10 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
MyAspect.before
ApsectBiz.biz
MyAspect.afterthrowing
MyAspect.after
(五)Around advice
注意:通知方法的第一个参数必ProceedingJoinPoint类型
例子:
修改一下切面类MyAspect(添加around方法):
package com.aop.schema; import org.aspectj.lang.ProceedingJoinPoint; /**
*
* 切面类
*
*/
public class MyAspect { public void before(){
System.out.println("MyAspect.before");
} public void afterreturning(){
System.out.println("MyAspect.afterreturning");
} public void afterthrowing(){
System.out.println("MyAspect.afterthrowing");
} public void after(){
System.out.println("MyAspect.after");
} public void around(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("MyAspect.around_1");
Object obj=pjp.proceed();
System.out.println("MyAspect.around_2");
}
}
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-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <bean id="myAspect" class="com.aop.schema.MyAspect"></bean> <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean> <aop:config>
<aop:aspect id="myAspectAOP" ref="myAspect">
<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />
<aop:before method="before" pointcut-ref="myPointcut"/>
<aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>
<aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>
<aop:after method="after" pointcut-ref="myPointcut"/>
<aop:around method="around" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config> </beans>
单元测试同上:
结果:
七月 09, 2015 11:15:20 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 23:15:20 CST 2015]; root of context hierarchy
七月 09, 2015 11:15:20 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
MyAspect.before
MyAspect.around_1
ApsectBiz.biz
java.lang.RuntimeException
at com.aop.schema.ApsectBiz.biz(ApsectBiz.java:11)
at com.aop.schema.ApsectBiz$$FastClassBySpringCGLIB$$ae10254d.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at com.aop.schema.MyAspect.around(MyAspect.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:43)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.aop.schema.ApsectBiz$$EnhancerBySpringCGLIB$$1fbf7bae.biz(<generated>)
at com.aop.schema.UnitTest.test(UnitTest.java:13)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
MyAspect.after
MyAspect.afterreturning
PS:有异常,仔细看,原来是around(ProceedingJoinPoint pjp)的try catch捕捉到了biz()抛出的异常,现在把异常注释掉(try catch里面怎么处理异常?这里要看具体的业务需要,这里先注释掉)
package com.aop.schema;
/**
*
* 业务类
*
*/
public class ApsectBiz { public void biz(){
System.out.println("ApsectBiz.biz");
//throw new RuntimeException(); //故意抛出异常
}
}
测试结果:
七月 09, 2015 11:18:17 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 23:18:17 CST 2015]; root of context hierarchy
七月 09, 2015 11:18:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-aop.xml]
MyAspect.before
MyAspect.around_1
ApsectBiz.biz
MyAspect.around_2
MyAspect.after
MyAspect.afterreturning
Spring学习(21)--- AOP之Advice应用(上)的更多相关文章
- Spring学习之AOP的实现方式
Spring学习之AOP的三种实现方式 一.介绍AOP 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能 ...
- spring学习(二) ———— AOP之AspectJ框架的使用
前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...
- Spring学习之AOP总结帖
AOP(面向方面编程),也可称为面向切面编程,是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP). 在进行 OOP 开发时,都是基于对组件(比如类)进行开发,然后对组件进行组 ...
- Spring学习之AOP
Spring-AOP(Aspect-orented programming) 在业务流程中插入与业务无关的逻辑,这样的逻辑称为Cross-cutting concerns,将Crossing-cutt ...
- Spring学习之Aop的各种增强方法
AspectJ允许使用注解用于定义切面.切入点和增强处理,而Spring框架则可以识别并根据这些注解来生成AOP代理.Spring只是使用了和AspectJ 5一样的注解,但并没有使用AspectJ的 ...
- Spring学习之Aop的基本概念
转自:http://my.oschina.net/itblog/blog/209067 AOP的基本概念 AOP从运行的角度考虑程序的流程,提取业务处理过程的切面.AOP面向的是程序运行中的各个步骤, ...
- Spring学习之AOP与事务
一.概述 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续, ...
- spring学习笔记-AOP
1.aop:aspect oriented programming 面向切面编程 2.aop在spring中的作用: 提供声明式服务(声明式事务) 允许用户实现自定义切面 3.aop:在不改变原有 ...
- Spring 学习二-----AOP的原理与简单实践
一.Spring AOP的原理 AOP全名Aspect-Oriented Programming,中文直译为面向切面(方面)编程.何为切面,就比如说我们系统中的权限管理,日志,事务等我们都可以将其看 ...
- Spring学习之==>AOP
一.概述 AOP(Aspect Oriented Programming)称为面向切面编程,在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等,Struts2的拦截器设计就是基于A ...
随机推荐
- JQuery实现通过点击标题切换字体
这个主要通过判断被点击的元素的子元素中是否包含了b元素来进行字体的切换,其中wrapInner函数是为了在$author元素的内部添加b标签. 切换回正常字体是通过将内容转化为纯文本形式,再替换元素内 ...
- JS基础部分小结
[使用js的三种方式] 1.HTML标签中内嵌JS(不提倡使用) 2.HTML页面中直接使用JS <script type="text/javascript"> JS代 ...
- Xmind 体验分享
Xmind 8 体验 初识思维脑图 这两天在学习使用思维脑图(xmind是其中一款软件)ing,在体验了一把思维脑图的使用后,深深感受到了脑洞大开的魔力. 从昨晚开始研究使用,到今天晚上截止,自己试着 ...
- copyWithZone 的使用方法
1.简单复制只能实现浅拷贝:指针赋值,使两个指针指向相同的一块内存空间,操作不安全. 2. Foundation类已经遵守了<NSCopying>和 <NSMutableCopyin ...
- JavaScript 复制对象
在JavaScript这门语言中,数据类型分为两大类:基本数据类型和复杂数据类型.基本数据类型包括Number.Boolean.String.Null.String.Symbol(ES6 新增),而复 ...
- ng-options语法详解
我们先看下options的这条语句 ng-options="value.id as value.label group by value.group for value in myOptio ...
- css 3d 基础知识
css3d 总结 3d transform (3D变形)(rotate skew scale translate) 基础知识 perspective (视距,景深) perspective-origi ...
- fopen的使用小记
整理自https://msdn.microsoft.com/zh-cn/library/t3ayayh1(VS.80).aspx errno, _doserrno, _sys_errlist, and ...
- Win下安装MySQL 5.6
最近身边有人要win下安装mysql 去学习数据库,问我如何安装MySQL,其实win 下安装要比Linux简单的多,直接运行安装包下一步安装即可. 1.首先我们运行mysql-installer-c ...
- Natas Wargame Level 16 Writeup(Content-based Blind SQL Injection)
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAqwAAADhCAYAAAANm+erAAAABHNCSVQICAgIfAhkiAAAIABJREFUeF