AOP切面通知
需要用的基本的jar包:
aopalliance-1.0.jar
aspectj-1.6.8.jar
aspectjweaver-1.6.8.jar
commons-logging-1.1.3.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
1:基于注解的日志通知和验证通知:
定义接口:
package com.yinfu.spring.aop.impl;
public interface ArithmeticCalculator {
public int add(int i,int j);
public int sub(int i,int j);
public int mul(int i,int j);
public int div(int i,int j);
}
定义实现类:
package com.yinfu.spring.aop.impl;
import org.springframework.stereotype.Component;
@Component("arithmeticCalculator")
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
@Override
public int add(int i, int j) {
int result = i+j;
return result;
}
@Override
public int sub(int i, int j) {
int result = i-j;
return result;
}
@Override
public int mul(int i, int j) {
int result = i*j;
return result;
}
@Override
public int div(int i, int j) {
int result = i/j;
return result;
}
}
定义spring的配置文件:applicationContext.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/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-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- <bean id="helloWorld" class="com.yinfu.spring.beans.HelloWorld">
<property name="name" value="fuck"></property>
</bean> -->
<!-- 配置自动扫描包 -->
<context:component-scan base-package="com.yinfu.spring.aop.impl"></context:component-scan> <!-- 使AspectJ注解起作用:自动为匹配的类生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
定义切面类:
package com.yinfu.spring.aop.impl; import java.util.Arrays;
import java.util.List; import org.aspectj.lang.JoinPoint;
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.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 把此类声明为一个切面
* 首相把该类放到IOC容器中,然后在声明为切面
* @Aspect声明此类是一个切面
* @Order声明切面的优先级,值越小优先级越高
* @author lusong
*
*/
@Order(1)
@Aspect
@Component
public class LoggingAspect { //定义一个方法用于声明切入点表达式,因为表达式都相同,可以进行封装不过方法内不需要添加其他代码
//使用@Pointcut声明切入点表达式
/**
* 此时下面的通知注解都可以将value值写成此方法名 如:@Before("declareJoinPointException()")即可
*/
@Pointcut("execution(public int com.yinfu.spring.aop.impl.ArithmeticCalculatorImpl.*(int, int))")
public void declareJoinPointException(){} //1.前置通知:声明该方法是一个前置方法,在指定目标方法之前执行
/**
* before中写的是aspectj的表达式
* public int可以用*代替,代表:任意修饰符和任意返回值
* com.yinfu.spring.aop.impl代表包名
* ArithmeticCalculatorImpl代表类名,可以用*代替,代表该包下的任意类
* add代表方法名,可以用*好代替,代表该类下的任意方法
* (int,int)参数类型,可以用..代替
* @param joinPoint 链接点利用此链接点可以得到代理对象中的方法名称和参数等细节
*/
@Before("execution(public int com.yinfu.spring.aop.impl.ArithmeticCalculatorImpl.*(int, int))")
public void beforeMethod(JoinPoint joinPoint ){
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("this method "+methodName+" begin"+args);
}
//2.后置通知:在目标方法执行后(无论是否发生异常),执行的通知
//后置通知中还不能访问目标方法执行的结果
@After("execution(public int com.yinfu.spring.aop.impl.ArithmeticCalculatorImpl.*(int, int))")
public void afterMethod(JoinPoint joinPoint ){
String methodName = joinPoint.getSignature().getName();
System.out.println("this method "+methodName+" end");
} //3返回通知:在目标方法正常执行后,执行的通知
//返回通知是可以访问到方法的返回值的
@AfterReturning(value="execution(public int com.yinfu.spring.aop.impl.ArithmeticCalculatorImpl.*(int, int))",returning="result")
public void afterReturning(JoinPoint joinPoint ,Object result){
String methodName = joinPoint.getSignature().getName();
System.out.println("this method "+methodName+" end with "+result);
} //4.异常通知:在目标方法出现异常时会执行代码
//可以访问异常对象,指定异常类型,当出现指定的异常时才会执行代码
//也就是Exception可以换成NullPoinException异常,当出现空指针异常的时候才会执行异常通知,其他异常不执行
@AfterThrowing(value="execution(public int com.yinfu.spring.aop.impl.ArithmeticCalculatorImpl.*(int, int))",throwing="ex")
public void afterThrowing(JoinPoint joinPoint ,Exception ex){
String methodName = joinPoint.getSignature().getName();
System.out.println("this method "+methodName+" throw with "+ex);
} //5.环绕通知
//环绕通知携带ProceedingJoinPoint类型的参数
//环绕通知类似于动态代理的全过程,ProceedingJoinPoint类型的参数可以决定是否执行目标方法
//环绕通知必须有返回值,返回值即为目标方法的返回值
@Around("execution(public int com.yinfu.spring.aop.impl.ArithmeticCalculatorImpl.*(int, int))")
public Object aroundMethod(ProceedingJoinPoint pjp){
Object result = null;
String methodName = pjp.getSignature().getName();
Object[] args = pjp.getArgs();
//执行目标方法
try {
//前置通知
System.out.println("this aroundMethod "+methodName+" begin with "+Arrays.asList(args));
result = pjp.proceed();
//返回通知
System.out.println("this aroundMethod "+methodName+" resutn with "+result);
} catch (Throwable e) {
//异常通知
System.out.println("this aroundMethod "+methodName+" throw with "+e);
}
//后置通知
System.out.println("this aroundMethod "+methodName+" end ");
return result;
} }
2.基于配置文件的日志通知和验证通知:
将类中的注解全部去掉,其他不变
此时的配置文件applicationContext.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/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-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置方法对象bean -->
<bean id="arithmeticCalculator" class="com.yinfu.spring.aop.impl.ArithmeticCalculatorImpl"></bean>
<!-- 配置切面bean -->
<bean id="loggingAspect" class="com.yinfu.spring.aop.impl.LoggingAspect"></bean>
<!-- 配置AOP切面 -->
<aop:config>
<!-- 配置切点表达式 -->
<aop:pointcut expression="execution(public int com.yinfu.spring.aop.impl.ArithmeticCalculatorImpl.*(int, int))" id="pointcut"/>
<!-- 配置切点及通知 -->
<aop:aspect ref="loggingAspect" order="1">
<aop:before method="beforeMethod" pointcut-ref="pointcut"/>
<aop:after method="afterMethod" pointcut-ref="pointcut"/>
<!-- 这里的returning值必须与切面类中定义的值是一样的 -->
<aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
<!-- 这里的throwing值必须与切面类中定义的值是一样的 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="ex"/>
<aop:around method="aroundMethod" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config> </beans>
AOP切面通知的更多相关文章
- 【spring】aop切面通知,日志处理
1.spring的切面编程 概念原理可以看这里:http://blog.csdn.net/moreevan/article/details/11977115 2.所需要的jar包 maven引入jar ...
- Spring AOP(通知、连接点、切点、切面)
一.AOP术语 通知(Advice) 切面的工作被称为通知.通知定义了切面是什么以及何时使用.除了描述切面要完成的工作,通知还解决了何时执行这个工作的问题.5种通知类型: 前置通知(Before): ...
- spring aop环绕通知
[Spring实战]—— 9 AOP环绕通知 假如有这么一个场景,需要统计某个方法执行的时间,如何做呢? 典型的会想到在方法执行前记录时间,方法执行后再次记录,得出运行的时间. 如果采用Sprin ...
- Spring切面通知执行的顺序(Advice Order)
问题描述 如果在Spring的程序中同时定义了环绕通知(Around)和前置通知(Before)..那么,有以下问题: 1.怎么让两个切面通知都起作用 2.或者让两者切面按自己指定的顺序进行执行? 3 ...
- Spring MVC通过AOP切面编程 来拦截controller 实现日志的写入
首选需要参考的是:[参考]http://www.cnblogs.com/guokai870510826/p/5977948.html http://www.cnblogs.com/guokai8 ...
- Spring基础篇——Spring的AOP切面编程
一 基本理解 AOP,面向切面编程,作为Spring的核心思想之一,度娘上有太多的教程啊.解释啊,但博主还是要自己按照自己的思路和理解再来阐释一下.原因很简单,别人的思想终究是别人的,自己的理解才是 ...
- Springboot项目使用aop切面保存详细日志到ELK日志平台
上一篇讲过了将Springboot项目中logback日志插入到ELK日志平台,它只是个示例.这一篇来看一下实际使用中,我们应该怎样通过aop切面,拦截所有请求日志插入到ELK日志系统.同时,由于往往 ...
- Spring中AOP切面编程学习笔记
注解方式实现aop我们主要分为如下几个步骤: 1.在切面类(为切点服务的类)前用@Aspect注释修饰,声明为一个切面类. 2.用@Pointcut注释声明一个切点,目的是为了告诉切面,谁是它的服务对 ...
- SpringBoot 通过自定义注解实现AOP切面编程实例
一直心心念的想写一篇关于AOP切面实例的博文,拖更了许久之后,今天终于着手下笔将其完成. 基础概念 1.切面(Aspect) 首先要理解‘切’字,需要把对象想象成一个立方体,传统的面向对象变成思维,类 ...
随机推荐
- Spark SQL数据载入和保存实战
一:前置知识具体解释: Spark SQL重要是操作DataFrame,DataFrame本身提供了save和load的操作. Load:能够创建DataFrame. Save:把DataFrame中 ...
- Office PDF如何旋转页面之后保存
直接视图-旋转视图-逆时针,是不行的,旋转之后无法保存,另存为之后也再打开也没有效果. 要点击视图-工具-页面 然后在右边的菜单中点击旋转,然后执行旋转,然后就可以保存了.
- 社交O2O的进化
引言 谁都想在O2O这个狂热的概念下分一杯羹,从O2O兴趣社交延伸到O2O生活服务,移动社交APP也是各显神通. 早在微信4.2版本号里,开机界面里那句"少发微信.多和朋友见见面" ...
- 积跬步,聚小流------ps有用小技巧,改变png图标颜色
* 实现效果: 原图: 改动后: * 实现目的: 满足为实现不同界面色彩搭配改动png图标的颜色 * 实现方法: 1.打开Photoshop工具,导入须要进行改动的png图标: 2.对导入的图 ...
- OpenGL中视点模型坐标的理解
个人的理解: gluLookAt中的eye.center和up的坐标原点是ModelView中的坐标原点,右手坐标系,Z轴正向指向显示器外侧 glOrtho中的near和far参数距离相对eye而言, ...
- 嵌入式开发之davinci---dm8168VPORT口管脚总结
http://blog.csdn.net/shanghaiqianlun/article/details/7531365
- 【iOS系列】-UIWebView加载网页禁止左右滑动
[iOS系列]-UIWebView加载网页禁止左右滑动 问题: 做项目时候,用UIWebView加载网页的时候,要求是和微信网页中打开的网页的效果一样,也即是只能上下滑动,不能左右滑动,也不能缩放. ...
- [C#]从URL中获取路径的最简单方法-new Uri(url).AbsolutePath
今天在写代码时遇到这样一个问题: 如何从字符串 "http://job.cnblogs.com/images/job_logo.gif" 中得到 "/images/job ...
- 用javascript写一个前端等待控件
前端等待控件有啥新奇的?什么jquery啦,第三方控件啦,好多好多,信手拈来. 因为项目使用了bootstrap的原因,不想轻易使用第三方,怕不兼容.自己写一个. 技术点包括动态加载CSS,javas ...
- asp.net MVC 中呈现指定区域下的分部视图
Html.RenderAction() 可以呈现分部视图. asp.net MVC就是有这种好处,可以将多个子视图无缝合成到一个视图上再输出,那么开发的时候,能够进行模块化开发.看上去同属一个页面上的 ...