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) 首先要理解‘切’字,需要把对象想象成一个立方体,传统的面向对象变成思维,类 ...
随机推荐
- java . 请在小于99999的正整数中找符合下列条件的数,它既是完全平方数,又有两位数字相同,如:144,676。
import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; //请在小于99999的正整数中找符合下列条件的 ...
- django 简易博客开发 4 comments库使用及ajax支持
首先还是贴一下源代码地址 https://github.com/goodspeedcheng/sblog 上一篇文章我们介绍了静态文件使用以及如何使用from实现对blog的增删改,这篇将介绍如何给 ...
- Visual Studio VS如何拷贝一个项目的窗体文件到另一个项目
1 比如下我有一个项目,我要把这个Config整个窗体和代码拷贝到另一个项目 2 在新项目中添加现有项,然后把这个窗体相关的三个文件都添加到新的项目中 3 然后在新窗体中就什么都有了 ...
- 再谈OpenCV
虽然之前写过一篇关于OpenCV的介绍(http://blog.csdn.net/carson2005/article/details/5822149).但依旧有朋友对其不甚了解.所以,常常能碰到有人 ...
- UICollectionView 具体解说学习
UICollectionView 和UITableView非常像,是APPLE公司在iOS 6后推出的用于处理图片这类UITableView 布局困难的控件,和UITableView 一样,它也有自己 ...
- ubuntu 安装后要做的事情
1. 安装chrome,软件中心就可以. 2. 安装vim 和一些插件.这里引入一大牛配置的插件集 sudo apt-get install vim-gtk wget -qO- https://raw ...
- 初探active mq
mq(message queue),即消息队列,目前比较流行消息队列是active mq 和kafka.本文介绍如何简单的使用active mq. ActiveMQ官网下载地址:http://acti ...
- 关于wireshark
1 对https进行抓包,或者说抓包经过了ssl加密的包 只要有rsa private key就可以了. https://wiki.wireshark.org/SSL 2 对浏览器访问的https的网 ...
- BootstrapValidator demo
source:http://bv.doc.javake.cn/api/ BootstrapValidator is the best jQuery plugin to validate form fi ...
- 有关MAC、PHY和MII
这是一篇转载,原文链接:http://www.cppblog.com/totti1006/archive/2008/04/22/47829.html 以太网(Ethernet)是一种计算机局域网组网技 ...