spring-第十八篇之spring AOP基于XML配置文件的管理方式
1、在XML配置文件中配置切面、切入点、增强处理。spring-1.5之前只能使用XML Schema方式配置切面、切入点、增强处理。
spring配置文件中,所有的切面、切入点、增强处理都必须定义在<aop:config.../>元素内部。<beans.../>元素可以包含多个<aop:config.../>元素,一个<aop:config>可以包含pointcut、advisor、aspect元素,且三个元素必须按照此顺序来定义。其中aspect下可以包含多个子元素。
使用<aop:config.../>方式进行配置时,可能与spring的自动代理方式相冲突,例如使用<aop:aspectj-autoproxy>或类似方式显示启用了自动代理,则可能导致出现问题(比如有些增强处理没有被织入)。所以要么全使用<aop:config.../>的配置方式,要么全使用自动代理方式,不要混合使用。
2、配置切面
使用<aop:aspect.../>定义,bean可以是Java bean也可以是容器bean(即可以给bean注入依赖),如果切面bean是容器bean,<aop:aspect.../>使用ref属性引用。使用<aop:aspect.../>可以指定的属性:
1》id:定义该切面的标识名。
2》ref:用于将ref引用的容器bean转换成切面bean。
3》order:指定该切面bean的优先级,该属性的作用与前面@AspectJ中的@Order注解、Ordered接口的作用完全一样,order属性值越小,该切面对应的优先级越高。
3、配置增强处理
使用XML配置增强处理需要以下元素:
<aop:before.../>:配置Before增强处理。
<aop:after.../> :配置After增强处理。
<aop:after-returning.../>:配置AfterReturning增强处理。
<aop:after-throwing.../>:配置AfterThrowing增强处理。
<aop:around.../>:配置Around增强处理。
这些元素都不支持使用子元素,但可以指定以下属性:
pointcut:指定一个切入点表达式,spring将在匹配该表达式的连接点时织入该增强处理。
pointcut-ref:该属性指定一个已经存在的切入点名称,通常pointcut、pointcut-ref两个属性只是用其中之一。
method:该属性指定一个方法名,指定将切面bean的该方法转换为增强处理。
throwing:该属性只对<after-throwing.../>元素有效,用于指定一个形参名,AfterThrowing增强处理方法可通过该形参访问目标方法所抛出的异常。
returning:该属性只对<after-returning.../>元素有效,用于指定一个形参名,AfterReturning增强处理方法可通过该形参访问目标方法的返回值。
当定义切入点表达式时,XML配置方式完全支持excution、within、args、this、target、bean等切入点指示符。
要组合切入点表达式时,使用的是and(相当于&&)、or(相当于||)、not(相当于!)
举个例子:
HelloImpl.java
package com.lfy.impl; import com.lfy.bean.Hello; /**
* 被增强的目标类
* @author lfy
*
*/
public class HelloImpl implements Hello { @Override
public void foo() { System.out.println("执行Hello组件的foo()方法");
} @Override
public void addUser(String name, String pass) { System.out.println("执行Hello组件的addUser()添加用户: "+name);
} @Override
public int addGroup(String groupName, int groupMemberNumber) { System.out.println("执行Hello组件的addGroup()添加群组: "+groupName);
if(groupMemberNumber<0||groupMemberNumber>100) {
throw new IllegalArgumentException("群组成员数在0~100之间");
}
return 0;
} @Override
public int fourAdviceGetParamer(String param) { System.out.println("执行Hello组件的fourAdviceGetParamer()方法,param:"+param);
return 5;
} }
FourAdviceGetParamerAspect.java
package com.lfy.aspect; import java.util.Arrays; 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.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; /**
* Around、Before、After、AfterReturning四种增强处理<br>
* 访问目标方法最简单的做法是定义增强处理方法时将第一个参数定义为JoinPoint类型,
* 当该增强处理方法被调用时,该JoinPoint参数就代表了织入增强处理的连接点。JoinPoint
* 提供了如下的常用访问方法:<br>
* 1>Objeact[] getArgs():返回目标方法的参数<br>
* 2>Signature getSignature():返回目标方法的相关信息<br>
* 3>Object getTarget():返回被增强处理的对象<br>
* 4>Object getThis():返回AOP框架为目标对象生成的代理对象。<br>
* 在这些方法中,只有Around增强处理中可以对目标方法的参数进行修改!<br>
* @author lfy
*
* 切入点组合连接符有&&、||、!
*/
public class FourAdviceGetParamerAspect { public Object processTx(ProceedingJoinPoint jp) throws Throwable { System.out.println("FourAdviceGetParamerAspect.Around执行目标方法之前,模拟开始事务...");
//获取目标方法原始的调用参数
Object[] args=jp.getArgs();
if(args!=null && args.length>0 && args[0].getClass() == String.class) {
//修改目标方法调用参数的第一个参数
args[0]="[增强的前缀]"+args[0];
}
//改变后的参数去执行目标方法,并保存目标方法执行后的返回值
Object rvt=jp.proceed(args);
System.out.println("FourAdviceGetParamerAspect.Around执行目标方法之后,模拟结束事务...");
System.out.println("<---------------->");
//如果rvt的类型是Integer,将rvt改为它的平方
if(rvt!=null&&rvt instanceof Integer) {
rvt=(Integer)rvt*(Integer)rvt;
}
return rvt;
} public void authority(JoinPoint jp) { System.out.println("FourAdviceGetParamerAspect.Before模拟执行权限检查");
//返回被织入增强的目标方法
System.out.println("被织入的目标方法是: "+jp.getSignature().getName());
System.out.println("被织入的目标方法的参数: "+Arrays.toString(jp.getArgs()));
System.out.println("被织入增强处理的目标对象为: "+jp.getTarget());
System.out.println("<---------------->");
} public void release(JoinPoint jp) { System.out.println("FourAdviceGetParamerAspect.After模拟方法结束后的释放资源...");
//返回被织入增强的目标方法
System.out.println("被织入的目标方法是: "+jp.getSignature().getName());
System.out.println("被织入的目标方法的参数: "+Arrays.toString(jp.getArgs()));
System.out.println("被织入增强处理的目标对象为: "+jp.getTarget());
System.out.println("<---------------->");
} public void log(JoinPoint jp,Object rvt) { System.out.println("FourAdviceGetParamerAspect.AfterReturning获取目标方法返回值: "+rvt);
System.out.println("FourAdviceGetParamerAspect.AfterReturning模拟记录日志功能...");
//返回被织入增强的目标方法
System.out.println("被织入的目标方法是: "+jp.getSignature().getName());
System.out.println("被织入的目标方法的参数: "+Arrays.toString(jp.getArgs()));
System.out.println("被织入增强处理的目标对象为: "+jp.getTarget());
System.out.println("<---------------->");
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 -->
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <aop:config>
<!-- 配置全局切入点,设置在<aop:config>下是全局切入点标签,
可以被多个切面共享。设置在<aop:aspect>下是某个切面的
切入点标签 ,表示该切入点只能在该切面中有效。
-->
<aop:pointcut id="myPointcut0" expression="execution(int com.lfy.impl.HelloImpl.fourAdviceGetParamer(..))"/> <!-- 将fourAdviceGetParamerBean转换成切面bean,切面
bean的名称为fourAdviceGetParamerAspect,指定该
切面的优先级为2
-->
<aop:aspect id="fourAdviceGetParamerAspect" ref="fourAdviceGetParamerBean" order="2">
<!-- 直接指定切入点表达式 -->
<aop:around pointcut="execution(int com.lfy.impl.HelloImpl.fourAdviceGetParamer(..))" method="processTx"/>
<aop:before pointcut-ref="myPointcut0" method="authority"/>
<!-- 定义一个After增强处理,直接指定切入点,以切面bean(即:fourAdviceGetParamerAspect)中的release()方法作为增强处理方法 -->
<aop:after pointcut-ref="myPointcut0" method="release"/>
<aop:after-returning pointcut-ref="myPointcut0" method="log" returning="rvt"/>
</aop:aspect>
</aop:config> <bean id="fourAdviceGetParamerBean" class="com.lfy.aspect.FourAdviceGetParamerAspect"/>
<bean id="hello" class="com.lfy.impl.HelloImpl"/>
<bean id="world" class="com.lfy.impl.WorldImpl"/>
</beans>
SpringAOPTest.java
package com.lfy.main; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.lfy.bean.Hello;
import com.lfy.bean.World; /**
* 2、基于XML Schema方式
* @author lfy
* 未登记的知识点:
* 1>指定增强处理的优先级,@Order注解及Orderd接口
* 2>切入点指示符
*/
public class SpringAOPTest { public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");
Hello hello=ctx.getBean("hello", Hello.class);
System.out.println("修改后的目标方法的返回值:"+hello.fourAdviceGetParamer("唐僧")); } }
运行结果:
4、配置切入点
XML配置方式也可以通过定义切入点来重复使用切入点表达式。spring提供了<aop:pointcut.../>元素定义切入点。当把<aop:pointcut.../>元素作为<aop:config.../>元素的子元素定义时,表明该切入点可被多个切面共享;当把<aop:pointcut.../>元素作为<aop:aspect.../>的子元素定义时,表明该切入点只能在该切面中有效。
配置<aop:pointcut.../>元素通常需要指定的属性有:
id:指定该切入点的标识名。
expression:指定该切入点关联的切入点表达式。
<aop:pointcut id="myPointcut0" expression="execution(int com.lfy.impl.HelloImpl.fourAdviceGetParamer(..))"/>
如果已经使用了注解定义了某个切入点,也可以给expression指定该已有的切入点。(但不推荐注解和XML Schema混合使用,我们在第十七篇讲过,容易出错。)
<aop:pointcut id="myPointcut0" expression="com.lfy.aspect.PointcutUtil.myPointcut()"/>
spring-第十八篇之spring AOP基于XML配置文件的管理方式的更多相关文章
- 8 -- 深入使用Spring -- 4...6 AOP代理:基于注解的XML配置文件的管理方式
8.4.6 基于XML配置文件的管理方式 Spring 2.x 提供一个新的aop:命名空间来定义切面.切入点和增强处理. XML配置方式优点: ⊙ 如果应用没有使用JDK 1.5 以上版本,那么应用 ...
- Spring Boot(十八):使用Spring Boot集成FastDFS
Spring Boot(十八):使用Spring Boot集成FastDFS 环境:Spring Boot最新版本1.5.9.jdk使用1.8.tomcat8.0 功能:使用Spring Boot将文 ...
- Spring(十八):Spring AOP(二):通知(前置、后置、返回、异常、环绕)
AspectJ支持5种类型的通知注解: @Before:前置通知,在方法执行之前执行: @After:后置通知,在方法执行之后执行: @AfterRunning:返回通知,在方法返回结果之后执行(因此 ...
- (转)Spring Boot(十八):使用 Spring Boot 集成 FastDFS
http://www.ityouknow.com/springboot/2018/01/16/spring-boot-fastdfs.html 上篇文章介绍了如何使用 Spring Boot 上传文件 ...
- Spring Boot(十八):使用 Spring Boot 集成 FastDFS
上篇文章介绍了如何使用 Spring Boot 上传文件,这篇文章我们介绍如何使用 Spring Boot 将文件上传到分布式文件系统 FastDFS 中. 这个项目会在上一个项目的基础上进行构建. ...
- Spring(十九):Spring AOP(三):切面的优先级、重复使用切入点表达式
背景: 1)指定切面优先级示例:有的时候需要对一个方法指定多个切面,而这多个切面有时又需要按照不同顺序执行,因此,切面执行优先级别指定功能就变得很实用. 2)重复使用切入点表达式:上一篇文章中,定义前 ...
- 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探
SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...
- Spring Boot 2.X(十八):集成 Spring Security-登录认证和权限控制
前言 在企业项目开发中,对系统的安全和权限控制往往是必需的,常见的安全框架有 Spring Security.Apache Shiro 等.本文主要简单介绍一下 Spring Security,再通过 ...
- 跟我学SpringCloud | 第八篇:Spring Cloud Bus 消息总线
SpringCloud系列教程 | 第八篇:Spring Cloud Bus 消息总线 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特 ...
随机推荐
- linux下查看某个文件位置的方法
linux下查看某个文件位置的方法: 例如,不知道apache的配置文件httpd.conf的位置,可以有两种方法来查看: 1.find / -name httpd.conf2.locate http ...
- Windows10测试低版本IE方法
前端开发工程师可能了解IETester是一款IE多版本兼容性测试软件,但是只支持Windows Xp,Vista,7,8系统,Windows10是不支持的,网上所说的开启.net framework ...
- ant-design如果按需加载组件
Ant Design React按需加载 Ant Design是阿里巴巴为React做出的组件库,有统一的样式及一致的用户体验 官网地址:https://ant.design 1.安装: npm in ...
- Scala本地安装
一.下载 https://www.scala-lang.org/download/ 这里我选择Scala2.10.4版本 二.安装 安装比较简单 和jdk类似 点击一路安装: 选择自己的路径 完成 ...
- websocket和基于swoole的简易即时通讯
这里描述个基于swoole的websocket 匿名群聊 UI <!DOCTYPE html> <html> <head> <meta charset=&qu ...
- uboot移植之迷雾解码
按照蜗窝科技的步骤执行 一.有关硬件描述的填空题 1)CPU上电后,从哪种设备( BOOTROM )的哪个地址( 0x0000_0000 )开始执 ...
- alert(1) to win 7
function escape(s) { // Pass inn "callback#userdata" var thing = s.split(/#/); if (!/^[a-z ...
- django之mysql数据库的配置和orm交互
一:django默认数据库的配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path. ...
- centos启动提示unexpected inconsistency RUN fsck MANUALLY
今天一台虚拟机背后的物理机故障了,主机迁移后变成了 read only filesystem.上面部署了很多长连接服务,没有关掉就直接reboot,报错: unexpected inconsisten ...
- Dump文件的生成
一.Windows系统的任务管理器里抓dump 启动任务管理器,选中某个进程,右键,弹出菜单"创建转储文件" 注意事项: 当你在64位Windows系统上抓32位进程的dmup文件 ...