springmvc配置AOP的两种方式
spingmvc配置AOP有两种方式,一种是利用注解的方式配置,另一种是XML配置实现。
应用注解的方式配置:
先在maven中引入AOP用到的依赖

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.1.RELEASE</version>
</dependency>
<!-- aop aspect注解导包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>

然后在springmvc的配置文件中加入AOP的配置,即扫描AOP的包以及让AOP生效
<!-- AOP 注解方式 ;定义Aspect -->
<!-- 激活组件扫描功能,在包"com.example.aop及其子包下面自动扫描通过注解配置的组件-->
<context:component-scan base-package="com.example.aop"/>
<!-- 启动AspectJ支持 只对扫描过的bean有效-->
<aop:aspectj-autoproxy proxy-target-class="true" />
然后加入AOP逻辑处理类

package com.example.aop; 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; @Aspect //该标签把LoggerAspect类声明为一个切面
@Order(1) //设置切面的优先级:如果有多个切面,可通过设置优先级控制切面的执行顺序(数值越小,优先级越高)
@Component //该标签把LoggerAspect类放到IOC容器中
public class LoggerAspect { /**
* 定义一个方法,用于声明切入点表达式,方法中一般不需要添加其他代码
* 使用@Pointcut声明切入点表达式
* 后面的通知直接使用方法名来引用当前的切点表达式;如果是其他类使用,加上包名即可
*/
@Pointcut("execution(public * com.example.controller.*Controller.*(..))")
public void declearJoinPointExpression(){} /**
* 前置通知
* @param joinPoint
*/
@Before("declearJoinPointExpression()") //该标签声明次方法是一个前置通知:在目标方法开始之前执行
public void beforMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("this method "+methodName+" begin. param<"+ args+">");
}
/**
* 后置通知(无论方法是否发生异常都会执行,所以访问不到方法的返回值)
* @param joinPoint
*/
@After("declearJoinPointExpression()")
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("this method "+methodName+" end.");
}
/**
* 返回通知(在方法正常结束执行的代码)
* 返回通知可以访问到方法的返回值!
* @param joinPoint
*/
@AfterReturning(value="declearJoinPointExpression()",returning="result")
public void afterReturnMethod(JoinPoint joinPoint,Object result){
String methodName = joinPoint.getSignature().getName();
System.out.println("this method "+methodName+" end.result<"+result+">");
}
/**
* 异常通知(方法发生异常执行的代码)
* 可以访问到异常对象;且可以指定在出现特定异常时执行的代码
* @param joinPoint
* @param ex
*/
@AfterThrowing(value="declearJoinPointExpression()",throwing="ex")
public void afterThrowingMethod(JoinPoint joinPoint,Exception ex){
String methodName = joinPoint.getSignature().getName();
System.out.println("this method "+methodName+" end.ex message<"+ex+">");
}
/**
* 环绕通知(需要携带类型为ProceedingJoinPoint类型的参数)
* 环绕通知包含前置、后置、返回、异常通知;ProceedingJoinPoin 类型的参数可以决定是否执行目标方法
* 且环绕通知必须有返回值,返回值即目标方法的返回值
* @param point
*/
@Around(value="declearJoinPointExpression()")
public Object aroundMethod(ProceedingJoinPoint point){ Object result = null;
String methodName = point.getSignature().getName();
try {
//前置通知
System.out.println("The method "+ methodName+" start. param<"+ Arrays.asList(point.getArgs())+">");
//执行目标方法
result = point.proceed();
//返回通知
System.out.println("The method "+ methodName+" end. result<"+ result+">");
} catch (Throwable e) {
//异常通知
System.out.println("this method "+methodName+" end.ex message<"+e+">");
throw new RuntimeException(e);
}
//后置通知
System.out.println("The method "+ methodName+" end.");
return result;
}
}

在类上加上注解Aspect声明这个类是一个切面,加上component注解加入IOC容器中。Order注解是优先级,如果只有一个切面类可以不用。注解pointcut是声明注解的作用范围。execution(public * com.example.controller.*Controller.*(..))我这里用的execution表达式,代表作用com.example.controller包下所有以Controller结尾类的所有Public方法。@pointcut所描述的方法里面通常不需要内容。切面通知包含:
前置通知(@Before,在执行方法之前,参数为JoinPoint)
后置通知(@After,无论方法抛不抛异常都会执行,所以获取不到方法的返回值。参数为JoinPoint)
返回通知(@AfterReturning,在方法正常结束后执行,可以获取到方法的返回值。参数为JoinPoint和result(Object))
异常通知(@AfterThrowing,在方法抛出异常时执行,可以获取到异常对象,且可以指定在出现特定异常时执行的代码,参数为JoinPoint何Exception)
环绕通知(@Around,环绕通知需要携带的类型为ProceedingJoinPoint类型的参数, 环绕通知包含前置、后置、返回、异常通知;ProceedingJoinPoin 类型的参数可以决定是否执行目标方法,且环绕通知必须有返回值,返回值即目标方法的返回值)
应用XML方式配置
依赖的话,应该不用加入AOP注解的依赖。先定义一个类,作为切面类。

package com.example.aop; import java.util.Arrays;
import java.util.List; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.stereotype.Component; @Component //该标签把LoggerAspect类放到IOC容器中
public class SysAspect { /**
* 前置通知
* @param joinPoint
*/
public void beforMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("this method "+methodName+" begin. param<"+ args+">");
}
/**
* 后置通知(无论方法是否发生异常都会执行,所以访问不到方法的返回值)
* @param joinPoint
*/
public void afterMethod(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println("this method "+methodName+" end.");
}
/**
* 返回通知(在方法正常结束执行的代码)
* 返回通知可以访问到方法的返回值!
* @param joinPoint
*/
public void afterReturnMethod(JoinPoint joinPoint,Object result){
String methodName = joinPoint.getSignature().getName();
System.out.println("this method "+methodName+" end.result<"+result+">");
}
/**
* 异常通知(方法发生异常执行的代码)
* 可以访问到异常对象;且可以指定在出现特定异常时执行的代码
* @param joinPoint
* @param ex
*/
public void afterThrowingMethod(JoinPoint joinPoint,Exception ex){
String methodName = joinPoint.getSignature().getName();
System.out.println("this method "+methodName+" end.ex message<"+ex+">");
}
/**
* 环绕通知(需要携带类型为ProceedingJoinPoint类型的参数)
* 环绕通知包含前置、后置、返回、异常通知;ProceedingJoinPoin 类型的参数可以决定是否执行目标方法
* 且环绕通知必须有返回值,返回值即目标方法的返回值
* @param point
*/
public Object aroundMethod(ProceedingJoinPoint point){ Object result = null;
String methodName = point.getSignature().getName();
try {
//前置通知
System.out.println("The method "+ methodName+" start. param<"+ Arrays.asList(point.getArgs())+">");
//执行目标方法
result = point.proceed();
//返回通知
System.out.println("The method "+ methodName+" end. result<"+ result+">");
} catch (Throwable e) {
//异常通知
System.out.println("this method "+methodName+" end.ex message<"+e+">");
throw new RuntimeException(e);
}
//后置通知
System.out.println("The method "+ methodName+" end.");
return result;
}
}

可以看到,这个类除了没有@Aspect以及相关切面的注解外,跟正常的AOP切面类没有差别。如果声明其让其为一个切面。需要我们在xml文件中手动配置。

<!-- 配置切面的Bean -->
<bean id="sysAspect" class="com.example.aop.SysAspect"/>
<!-- 配置AOP -->
<aop:config>
<!-- 配置切点表达式 -->
<aop:pointcut id="pointcut" expression="execution(public * com.example.controller.*Controller.*(..))"/>
<!-- 配置切面及配置 -->
<aop:aspect order="3" ref="sysAspect">
<!-- 前置通知 -->
<aop:before method="beforMethod" pointcut-ref="pointcut" />
<!-- 后置通知 -->
<aop:after method="afterMethod" pointcut-ref="pointcut"/>
<!-- 返回通知 -->
<aop:after-returning method="afterReturnMethod" pointcut-ref="pointcut" returning="result"/>
<!-- 异常通知 -->
<aop:after-throwing method="afterThrowingMethod" pointcut-ref="pointcut" throwing="ex"/>
<aop:around method="aroundMethod" pointcut-ref="pointcut"/>
springmvc配置AOP的两种方式的更多相关文章
- spring配置属性的两种方式
spring配置属性有两种方式,第一种方式通过context命名空间中的property-placeholder标签 <context:property-placeholder location ...
- web.config文件中配置数据库连接的两种方式
web.config文件中配置数据库连接的两种方式 标签: 数据库webconfig 2015-04-28 18:18 31590人阅读 评论(1)收藏举报 分类: 数据库(74) 在网站开发 ...
- MyBatis配置数据源的两种方式
---------------------siwuxie095 MyBatis 配置数据源的两种方式 1.配置方 ...
- Spring Boot配置过滤器的两种方式
过滤器(Filter)是Servlet中常用的技术,可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,常用的场景有登录校验.权限控制.敏感词过滤等,下面介绍下Spring Boot配置过 ...
- SpringMVC实现文件下载的两种方式及多文件下载
1.传统方法 @RequestMapping("/download") public String download( String fileName ,String filePa ...
- SpringMVC 返回json的两种方式
前后台数据交互使用json是一种很重要的方式.本文主要探讨SpringMVC框架使用json传输的技术. 请注意,本文所提到的项目使用Spring 版本是4.1.7,其他版本在具体使用上可能有不一样的 ...
- jdk配置java_home的两种方式
在开发java项目的时候,要先安装jdk,安装完jdk之后我们要配置环境变量.今天说一下java home环境变量. 配置环境变量有两种方式,一种就是在计算机的环境变量里面配置.这个是很简单的.如果你 ...
- SpringMVC实现Action的两种方式以及与Struts2的区别
4.程序员写的Action可采用哪两种方式? 第一.实现Controller接口第二.继承自AbstractCommandController接口 5.springmvc与struts2的区别? 第一 ...
- guice基本使用,配置模块的两种方式(三)
guice是使用module进行绑定的,它提供了两种方式进行操作. 第一种是继承AbstractModule抽象类. package com.ming.user.test; import com.go ...
随机推荐
- synchronized 线程同步
synchronized 通常用来形容一次方法的调用,调用一旦开始,调用者必须等到方法调用返回后,才能继续执行后续的操作. 1.demo package demo1; public class My ...
- 通过JSONP实现完美跨域
通过JSONP实现完美跨域 三水清 2010-06-11 20:17:47 以前我经常在博客说JSONP,例如我的WordPress天气插件就是通过JSONP来调用的天气数据,今天就说说通过JSONP ...
- XSS之浪潮已经来临
前些天和Roy厉在微博上聊到微信公众账号,我说我在辛苦运营“网站安全中心”这个账号呢,他说我这账号粉丝少是少了点,不过用户定位精确,我说我不希望精确,因为我在尽可能写科普,科普需要传播. Roy厉说过 ...
- ms sql 在任何位置 添加列
摘自: http://bbs.csdn.net/topics/40236129 在任何位置插入列:create proc addcolumn@tablename varchar(30), --表名@ ...
- Git 思想和工作原理
从根本上来讲,Git是一个内容寻址文件系统,并在此之上提供了一个版本控制系统的用户界面,它是一个非常强大且易用的工具,理解Git的工作原理,能够帮助我们更容易学习和使用Git. 本文不会像书籍里那样, ...
- 对Class.getResourceAsStream和ClassLoader.getResourceAsStream方法所使用的资源路径的解释
这是个非常基础的问题了,这里提供一些演示样例,帮助高速理解和记忆这个问题. 在该方法的文档:http://docs.oracle.com/javase/7/docs/api/java/lang/Cla ...
- 使用HTML5画布(canvas)生成阴影效果
来源:GBin1.com 使用HTML5的画布特性,我们可以创建图形,在这片文章中,我们将创建图形的阴影. var canvas = document.getElementById('shadowca ...
- c语言指针详解 经典
指针是C语言中广泛使用的一种数据类型. 运用指针编程是C语言最主要的风格之一.利用指针变量可以表示各种数据结构: 能很方便地使用数组和字符串: 并能象汇编语言一样处理内存地址,从而编出精练而高效的程序 ...
- Spark1.0.0 history server 配置
在执行Spark应用程序的时候,driver会提供一个webUI给出应用程序的执行信息.可是该webUI随着应用程序的完毕而关闭port,也就是说,Spark应用程序执行完后,将无法查看应用程序的历史 ...
- asp.net页面生命周期之页面的终结阶段
处理过回发事件之后,页面便为浏览器生成输出做好了准备.呈现阶段分为两部分:预呈现和标记生成.预呈现这个子阶段有两个事件表征,分别为:预处理和投递处理. PreRender事件 通过处理该事件,页面和控 ...