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. 行人重识别(ReID) ——基于MGN-pytorch进行可视化展示

    下载MGN-pytorch:https://github.com/seathiefwang/MGN-pytorch 下载Market1501数据集:http://www.liangzheng.org/ ...

  2. unity2017 光照与渲染(一)

    光照&渲染(基于unity2017.2.0) Custom Skybox 天空盒 最丰富的环境光 a. TextureShape 改成 Cube. b. 把图片直接丢给天空,就会自动生成材质. ...

  3. python时间测量

    使用自定义装饰器测量时间 def test_time(func): def inner(*args, **kw): t1 = datetime.datetime.now() print('开始时间:' ...

  4. 2019南京网赛 The beautiful values of the palace(思维,树状数组

    https://nanti.jisuanke.com/t/41298 题意:给一个n * n的螺旋矩阵,n保证是奇数,取一些点使其.获得价值,价值为数位和,然后再给q次查询,求矩阵中的价值总和 思路: ...

  5. 22.Express框架——2019年12月19日

    2019年12月19日14:16:36 1. express简介 1.1 介绍 Express框架是后台的Node框架,所以和jQuery.zepto.yui.bootstrap都不一个东西. Exp ...

  6. Centos7.5中的SElinux操作命令说明

    设置Selinux模式 setenforce 0 0表示警告模式 1表示强制模式 关闭要设置/etc/sysconfig/selinux下将"SELINUX=enforcing"改 ...

  7. C# WinForm 中Label自动换行 解决方法

    在TableLayoutPannel中放着一些Label如果把Label的AutoSize属性设成True的话,文字超过label长度时就会自动增加,直到后面的字出窗体以外设置成False时,一旦到达 ...

  8. [CSP-S模拟测试]:旋转子段(数学)

    题目描述 $ZYL$有$N$张牌编号分别为$1,2,...,N$.他把这$N$张牌打乱排成一排,然后他要做一次旋转使得旋转后固定点尽可能多.如果第$i$个位置的牌的编号为$i$,我们就称之为固定点.旋 ...

  9. HDU6672 Seq(找规律)

    HDU6672 Seq 对于递推式 \(a_n = (\sum_{i = 1}^{n-1}a_i * i)\%n\) 打表列出 \(a_i\) 的前 \(100\) 项,发现有以 \(6\) 为循环的 ...

  10. I/O等待事件-db file scattered read

    摘自:http://blog.csdn.net/zq9017197/article/details/7925338