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配置文件的管理方式的更多相关文章

  1. 8 -- 深入使用Spring -- 4...6 AOP代理:基于注解的XML配置文件的管理方式

    8.4.6 基于XML配置文件的管理方式 Spring 2.x 提供一个新的aop:命名空间来定义切面.切入点和增强处理. XML配置方式优点: ⊙ 如果应用没有使用JDK 1.5 以上版本,那么应用 ...

  2. Spring Boot(十八):使用Spring Boot集成FastDFS

    Spring Boot(十八):使用Spring Boot集成FastDFS 环境:Spring Boot最新版本1.5.9.jdk使用1.8.tomcat8.0 功能:使用Spring Boot将文 ...

  3. Spring(十八):Spring AOP(二):通知(前置、后置、返回、异常、环绕)

    AspectJ支持5种类型的通知注解: @Before:前置通知,在方法执行之前执行: @After:后置通知,在方法执行之后执行: @AfterRunning:返回通知,在方法返回结果之后执行(因此 ...

  4. (转)Spring Boot(十八):使用 Spring Boot 集成 FastDFS

    http://www.ityouknow.com/springboot/2018/01/16/spring-boot-fastdfs.html 上篇文章介绍了如何使用 Spring Boot 上传文件 ...

  5. Spring Boot(十八):使用 Spring Boot 集成 FastDFS

    上篇文章介绍了如何使用 Spring Boot 上传文件,这篇文章我们介绍如何使用 Spring Boot 将文件上传到分布式文件系统 FastDFS 中. 这个项目会在上一个项目的基础上进行构建. ...

  6. Spring(十九):Spring AOP(三):切面的优先级、重复使用切入点表达式

    背景: 1)指定切面优先级示例:有的时候需要对一个方法指定多个切面,而这多个切面有时又需要按照不同顺序执行,因此,切面执行优先级别指定功能就变得很实用. 2)重复使用切入点表达式:上一篇文章中,定义前 ...

  7. 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探

    SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...

  8. Spring Boot 2.X(十八):集成 Spring Security-登录认证和权限控制

    前言 在企业项目开发中,对系统的安全和权限控制往往是必需的,常见的安全框架有 Spring Security.Apache Shiro 等.本文主要简单介绍一下 Spring Security,再通过 ...

  9. 跟我学SpringCloud | 第八篇:Spring Cloud Bus 消息总线

    SpringCloud系列教程 | 第八篇:Spring Cloud Bus 消息总线 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如无特 ...

随机推荐

  1. 浅谈协议(二)——视频流协议 [RTP/RTCP/RTMP/HTTP_FLV]

  2. 修改 linux 默认字符集

    [root@eric6 ~]# cat /etc/sysconfig/i18n //查看 linux 默认的字符集,默认是 UTF-8 LANG="zh_CN.UTF-8" cp ...

  3. iconv 转换文件的编码格式

    1.命令功能 icnov用于转换文件的编码格式 linux默认中没有icnov文件,需要自己安装http://www.gnu.org/software/libiconv/. (1)下载libiconv ...

  4. ps:建立规则选区

    在前面的内容中,我们初步接触了色彩调整工具中的“色相/饱和度”工具[CTRL U],现在我们可以很容易地改变图像的色相.将如下左图的色相改为-100,形成如下中图的效果.但是这样做有一个局限,那就是只 ...

  5. [sql 注入] 注入类型

    基于整型的注入: url:http://localhost/?id=12 拼接sql:$sql = "select * from user where id = {$_GET['id']}& ...

  6. 【串线篇】spring boot日志框架

    一.日志框架 小张:开发一个大型系统: 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件? 2.框架来记录系统的一些运行时信息:日志框架 ...

  7. bzoj4002 [JLOI2015]有意义的字符串 特征根+矩阵快速幂

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4002 题解 神仙题. 根据下面的一个提示: \[ b^2 \leq d \leq (b+1)^ ...

  8. django之子应用中开发视图函数

    一:修改视图函数 报错:ImportError: No module named 'django' 原因是:pycharm中的解释器未选择虚拟环境里面的python3 from django.shor ...

  9. 033:DTL常用过滤器(2)

    date过滤器: date过滤器:将一个日期按照指定的格式,格式化成字符串.示例代码如下: views.py: from datetime import datetime def cur_date(r ...

  10. 一个能极大提高生产率的Chrome新建标签页扩展

    我是一个对开发生产率有着BT需求的程序员,总是追求将自己的单位时间生产率最大化. 通过分析,我发现自己一天会反反复复使用Chrome的新建标签,然后访问常用的网站.因此,我期望新建一个默认的Chrom ...