需要用的基本的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切面通知的更多相关文章

  1. 【spring】aop切面通知,日志处理

    1.spring的切面编程 概念原理可以看这里:http://blog.csdn.net/moreevan/article/details/11977115 2.所需要的jar包 maven引入jar ...

  2. Spring AOP(通知、连接点、切点、切面)

    一.AOP术语 通知(Advice)  切面的工作被称为通知.通知定义了切面是什么以及何时使用.除了描述切面要完成的工作,通知还解决了何时执行这个工作的问题.5种通知类型: 前置通知(Before): ...

  3. spring aop环绕通知

    [Spring实战]—— 9 AOP环绕通知   假如有这么一个场景,需要统计某个方法执行的时间,如何做呢? 典型的会想到在方法执行前记录时间,方法执行后再次记录,得出运行的时间. 如果采用Sprin ...

  4. Spring切面通知执行的顺序(Advice Order)

    问题描述 如果在Spring的程序中同时定义了环绕通知(Around)和前置通知(Before)..那么,有以下问题: 1.怎么让两个切面通知都起作用 2.或者让两者切面按自己指定的顺序进行执行? 3 ...

  5. Spring MVC通过AOP切面编程 来拦截controller 实现日志的写入

    首选需要参考的是:[参考]http://www.cnblogs.com/guokai870510826/p/5977948.html    http://www.cnblogs.com/guokai8 ...

  6. Spring基础篇——Spring的AOP切面编程

    一  基本理解 AOP,面向切面编程,作为Spring的核心思想之一,度娘上有太多的教程啊.解释啊,但博主还是要自己按照自己的思路和理解再来阐释一下.原因很简单,别人的思想终究是别人的,自己的理解才是 ...

  7. Springboot项目使用aop切面保存详细日志到ELK日志平台

    上一篇讲过了将Springboot项目中logback日志插入到ELK日志平台,它只是个示例.这一篇来看一下实际使用中,我们应该怎样通过aop切面,拦截所有请求日志插入到ELK日志系统.同时,由于往往 ...

  8. Spring中AOP切面编程学习笔记

    注解方式实现aop我们主要分为如下几个步骤: 1.在切面类(为切点服务的类)前用@Aspect注释修饰,声明为一个切面类. 2.用@Pointcut注释声明一个切点,目的是为了告诉切面,谁是它的服务对 ...

  9. SpringBoot 通过自定义注解实现AOP切面编程实例

    一直心心念的想写一篇关于AOP切面实例的博文,拖更了许久之后,今天终于着手下笔将其完成. 基础概念 1.切面(Aspect) 首先要理解‘切’字,需要把对象想象成一个立方体,传统的面向对象变成思维,类 ...

随机推荐

  1. linux的shell的until循环举例说明

    执行脚本: sh login.sh user,其中user为第一个参数 如下所示,如果用户‘user’登录,'who | grep "$1"'为true,until循环结束,程序继 ...

  2. linux定时重启节约内存

    linux服务器上运行的一些程序,比较消耗内存,需要定时重启,进行内存定期释放 0 2 * * *  sudo /sbin/reboot && echo $(date) '重启成功' ...

  3. leetCode 94.Binary Tree Inorder Traversal(二叉树中序遍历) 解题思路和方法

    Given a binary tree, return the inorder traversal of its nodes' values. For example: Given binary tr ...

  4. ES文件浏览器 WIFI 查看电脑文件怎么弄

    1 开启来宾账户   2 右击要共享的文件夹,添加Guest共享(如果只是要查看共享的资源,权限级别为读取即可)   3 共享之后,网络路径就是"\\"+你的计算机名+" ...

  5. 万恶之源:C语言中的隐式函数声明

    1 什么是C语言的隐式函数声明 在C语言中,函数在调用前不一定非要声明.如果没有声明,那么编译器会自己主动依照一种隐式声明的规则,为调用函数的C代码产生汇编代码.以下是一个样例: int main(i ...

  6. 利用wxpython编写GUI

    首先建立一个简单的布局合理的图形界面,但是其中按下按键没有事情发生 #encoding=utf-8 __author__ = 'heng' #编写一个GUI import wx app = wx.Ap ...

  7. NOI 2015 滞后赛解题报告

    报同步赛的时候出了些意外.于是仅仅能做一做"滞后赛"了2333 DAY1 T1离线+离散化搞,对于相等的部分直接并查集,不等部分查看是否在同一并查集中就可以,code: #incl ...

  8. HDU4763 Theme Section 【KMP】

    Theme Section Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  9. OpenCV基本图像容器Mat的几种创建方法

    參考文章:http://www.cnblogs.com/tornadomeet/archive/2012/07/19/2599376.html 实验说明: (引用) 本文主要讲一些opencv 2.0 ...

  10. 最简单的基于FFmpeg的移动端样例:IOS 视频转码器

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...