使用基于Schema的切面定义后,切点、增强类型的注解信息从切面类中剥离出来,原来的切面类也就蜕变为真正意义上的POJO了。

1、一个简单切面的配置

基于Schema配置的切面示例:

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<aop:config proxy-target-class="true">
<aop:aspect ref="adviceMethods">
<aop:before pointcut="target(com.yyq.schema.NaiveWaiter) and execution(* greetTo(..))"
method="preGreeting"/>
</aop:aspect>
</aop:config>
<bean id="adviceMethods" class="com.yyq.schema.AdviceMethods"/>
<bean id="naiveWaiter" class="com.yyq.schema.NaiveWaiter"/>
<bean id="naughtyWaiter" class="com.yyq.schema.NaughtyWaiter"/>
</beans>

  使用一个<aop:aspect>元素标签定义切面,其内部可以定义多个增强。在<aop:config>元素中可以定义多个切面。通过<aop:before>声明了一个前置增强,并通过pointcut属性定义切点表达式,切点表达式的语法和@AspectJ中所用的语法完全相同,由于&&在XML中使用不便,所以一般用and操作符代替。通过method属性指定增强的方法,该方法应该是adviceMethods Bean中的方法。

 
增强方法所在的类:

package com.baobaotao.schema;
import org.aspectj.lang.ProceedingJoinPoint; public class AdviceMethods {
public void preGreeting(String name) {
System.out.println("--how are you!--");
System.out.println(name);
}
//后置增强对应方法
public void afterReturning(int retVal){
System.out.println("----afterReturning()----");
System.out.println("returnValue:"+retVal);
System.out.println("----afterReturning()----");
}
//环绕增强对应方法
public void aroundMethod(ProceedingJoinPoint pjp){
System.out.println("----aroundMethod()----");
System.out.println("args[0]:"+pjp.getArgs()[0]);
System.out.println("----aroundMethod()----");
}
//抛出异常增强
public void afterThrowingMethod(IllegalArgumentException iae){
System.out.println("----afterThrowingMethod()----");
System.out.println("exception msg:"+iae.getMessage());
System.out.println("----afterThrowingMethod()----");
}
//final增强
public void afterMethod(){
System.out.println("----afterMethod()----");
} //------------绑定连接点参数----------//
public void bindParams(int num,String name){
System.out.println("----bindParams()----");
System.out.println("name:"+name);
System.out.println("num:"+num);
System.out.println("----bindParams()----");
}
}

NaiveWaiter类:

package com.yyq.schema;
public class NaiveWaiter implements Waiter {
@Override
public void greetTo(String name) {
System.out.println("NaiveWaiter:greet to " + name + "...");
}
@Override
public void serveTo(String name) {
System.out.println("NaiveWaiter:serving to " + name + "...");
}
public void smile(String clientName,int times){
System.out.println("NaiveWaiter:smile to "+clientName+ times+"times...");
}
}

NaughtyWaiter类:

package com.yyq.schema;
public class NaughtyWaiter implements Waiter {
public void greetTo(String clientName) {
System.out.println("NaughtyWaiter:greet to " + clientName + "...");
}
public void serveTo(String clientName) {
System.out.println("NaughtyWaiter:serving " + clientName + "...");
}
public void joke(String clientName, int times) {
System.out.println("NaughtyWaiter:play " + times + " jokes to " + clientName + "...");
}
}

测试方法:

package com.yyq;
import com.yyq.schema.Waiter;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SchemaTest {
@Test
public void schemaTest(){
String configPath = "com\\yyq\\schema\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter naiveWaiter = (Waiter)ctx.getBean("naiveWaiter");
Waiter naughtyWaiter = (Waiter)ctx.getBean("naughtyWaiter");
naiveWaiter.greetTo("John");
naughtyWaiter.greetTo("Tom");
}
}
输出结果:
---How are you !---
John
NaiveWaiter:greet to John...
NaughtyWaiter:greet to Tom...
 
2、配置命名切点
    通过pointcut属性声明的切点时匿名切点,它不能被其他增强或其他切面引用。Spring提供了命名切点的配置方式。
命名切点配置:

  <aop:config proxy-target-class="true">
<aop:aspect ref="adviceMethods">
<aop:pointcut id="greetToPointcut" expression="target(com.yyq.schema.NaiveWaiter) and execution(* greetTo(..))"/>
<aop:before method="preGreeting" pointcut-ref="greetToPointcut"/>
</aop:aspect>
</aop:config>

  使用<aop:pointcut>定义了一个切点,并通过id属性进行命名,通过pointcut-ref引用这个命名的切点。和<aop:before>一样,除了引介增强外,其他任意增强类型都拥有pointcut、pointcut-ref和method这3个属性。

    如果想要让一个切点为所有增强访问,定义如下:

 <aop:config proxy-target-class="true">
<aop:pointcut id="greetToPointcut2" expression="target(com.yyq.schema.NaiveWaiter) and execution(* greetTo(..))"/>
<aop:aspect ref="adviceMethods">
<aop:before method="preGreeting" pointcut-ref="greetToPointcut2"/>
</aop:aspect>
<aop:aspect ref="adviceMethods">
<aop:after method="postGreeting" pointcut-ref="greetToPointcut2"/>
</aop:aspect>
</aop:config>

3、各种增强类型的配置

1)后置增强

<aop:config proxy-target-class="true">
<aop:aspect ref="adviceMethods">
<aop:after-returning method="afterReturning"
pointcut="target(com.baobaotao.SmartSeller)" returning="retVal" />
</aop:aspect>
</aop:config>

2)环绕增强

 <aop:config proxy-target-class="true">
<aop:aspect ref="adviceMethods">
<aop:around method="aroundMethod"
pointcut="execution(* serveTo(..)) and within(com.baobaotao.Waiter)" />
</aop:aspect>
</aop:config>

3)抛出异常增强

<aop:config proxy-target-class="true">
<aop:aspect ref="adviceMethods">
<aop:after-throwing method="afterThrowingMethod"
pointcut="target(com.baobaotao.SmartSeller) and execution(* checkBill(..))"
throwing="iae" />
</aop:aspect>
</aop:config>

4)Final增强

 <aop:config proxy-target-class="true">
<aop:aspect ref="adviceMethods">
<aop:after method="afterMethod"
pointcut="execution(* com..*.Waiter.greetTo(..))" />
</aop:aspect>
</aop:config>

5)引介增强

<aop:config proxy-target-class="true">
<aop:aspect ref="adviceMethods">
<aop:declare-parents
implement-interface="com.baobaotao.Seller"
default-impl="com.baobaotao.SmartSeller"
types-matching="com.baobaotao.Waiter+" />
</aop:aspect>
</aop:config>
 
4、绑定连接点信息
    基于Schema配置的增强方法绑定连接点信息和基于@AspectJ绑定连接点信息所使用的方式没有区别。
    1)所有增强类型对应的方法第一个入参都可以声明为JoinPoint(环绕增强可声明为ProceedingJoinPoint)访问连接点信息;
    2)<aop:after-returning>(后置增强)可以通过returning属性绑定连接点方法的返回值,<aop:after-throwing>(抛出异常增强)可以通过throwing属性绑定连接点方法所抛出的异常;
    3)所有增强类型都可以通过可绑定参数的切点函数绑定连接点方法的入参。
绑定连接点采纳数到增强方法:

 <aop:config proxy-target-class="true">
<aop:aspect ref="adviceMethods">
<aop:before method="bindParams"
pointcut="target(com.yyq.schema.NaiveWaiter) and args(name,num,..)"/>
</aop:aspect>
</aop:config>

AdviceMethods绑定参数的增强方法:

//------------绑定连接点参数----------//
public void bindParams(int num,String name){
System.out.println("----bindParams()----");
System.out.println("name:"+name);
System.out.println("num:"+num);
System.out.println("----bindParams()----");
}
 
5、Advisor配置
    Advisor是Spring中切面概念的对应物,是切点和增强的复合体,不过仅包含一个切点和一个增强。在AspectJ中没有对应的等价物,在aop Schema配置样式中,可以通过<aop:advisor>配置一个Advisor。通过advice-ref属性引用基于接口定义的增强,通过pointcut定义切点表达式,或者通过pointcut-ref引用一个命名的切点。

  <aop:config proxy-target-class="true">
<aop:advisor advice-ref="testAdvice" pointcut="execution(* com..*.Waiter.greetTo(..))"/>
</aop:config>
<bean id="testAdvice" class="com.yyq.schema.TestBeforeAdvice"/>

 增强类:

package com.yyq.schema;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class TestBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target)
throws Throwable {
System.out.println("------TestBeforeAdvice------");
System.out.println("clientName:"+args[0]);
System.out.println("------TestBeforeAdvice------");
}
}
 

基于Schema配置切面的更多相关文章

  1. Spring 3.x企业应用开发实战(11)----基于@AspectJ配置切面

    1.@AspectJ的JDK必须是JDK 5.0+ 基于@AspectJ配置切面 @AspectJ采用注解描述切点.增强,两者只是表达式方式不同,效果相同. @AspectJ语法基础-----切点表达 ...

  2. 基于@AspectJ注解配置切面与基于XML配置切面

    1. Waiter目标类 package com.smart.aop.advice.pointcut; public class Waiter { public void greetTo(String ...

  3. 第三章 AOP 基于Schema的AOP

    基于Schema定义的切面和前现两种方式定义的切面,内容上都差不多,只是表现形式不一样而已. 3.7.1一般增强的使用 a.目标类 public class Target { public void ...

  4. Spring 基于XML配置

    基于XML的配置 对于基于XML的配置,Spring 1.0的配置文件采用DTD格式,Spring2.0以后采用Schema格式,后者让不同类型的配罝拥有了自己的命名空间,使得配置文件更具扩展性.此外 ...

  5. 基于Schema的AOP 配置使用详解

    原文地址:http://jinnianshilongnian.iteye.com/blog/1418598 基于Schema的AOP从Spring2.0之后通过"aop"命名空间来 ...

  6. 基于@AspectJ配置Spring AOP之一--转

    原文地址:http://tech.it168.com/j/2007-08-30/200708302209432.shtml 概述 在低版本Spring中定义一个切面是比较麻烦的,需要实现特定的接口,并 ...

  7. 一步一步深入spring(6)--使用基于XML配置的spring实现的AOP

    上节我们提到了使用基于注解实现的AOP,这节我们将用基于xml配置的方式来实现的AOP. 1.首先建立一个类,作为切面类,这个类主要用来实现注解中各种通知要实现的方法. package com.yan ...

  8. 开涛spring3(6.3) - AOP 之 6.3 基于Schema的AOP

    6.3  基于Schema的AOP 基于Schema的AOP从Spring2.0之后通过“aop”命名空间来定义切面.切入点及声明通知. 在Spring配置文件中,所以AOP相关定义必须放在<a ...

  9. spring aop 基于schema的aop

    AOP的基本概念: 连接点(Jointpoint):表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化.方法执行.方法调用.字段调用或处理异常等等,Spring只支持方法执行连接点,在AOP ...

随机推荐

  1. python之函数第二篇

    一.名称空间与作用域 名称空间分类: 内置名称空间 import this dir(buil-in) 查看全部内置 全局名称空间 局部名称空间 在函数体内等 查询全局和局部 globals()方法可以 ...

  2. Hibernate非主键关联

    一. 非主键关联,我们进行外键关联时,通常使用的是主键,但有时候需要使用到其他列时可以通过以下方法设置: 注解中:@JoinColumn(name="city", referenc ...

  3. javaScript系列 [06]-javaScript和this

    在javaScript系列 [01]-javaScript函数基础这篇文章中我已经简单介绍了JavaScript语言在函数使用中this的指向问题,虽然篇幅不长,但其实最重要的部分已经讲清楚了,这篇文 ...

  4. yuv rgb 互转 公式 及算法

    1 前言 自然界的颜色千变万化,为了给颜色一个量化的衡量标准,就需要建立色彩空间模型来描述各种各样的颜色,由于人对色彩的感知是一个复杂的生理和心理联合作用的过程,所以在不同的应用领域中为了更好更准确的 ...

  5. 卷积的三种模式:full, same, valid

    通常用外部api进行卷积的时候,会面临mode选择. 本文清晰展示三种模式的不同之处,其实这三种不同模式是对卷积核移动范围的不同限制. 设 image的大小是7x7,filter的大小是3x3 1,f ...

  6. js 图片base64转file文件的两种方式

    js 图片base64转file文件的两种方式 https://blog.csdn.net/yin13037173186/article/details/83302628 //将base64转换为bl ...

  7. Docker 安装和基础用法

    理解Docker(1):Docker 安装和基础用法 本系列文章将介绍Docker的有关知识: (1)Docker 安装及基本用法 (2)Docker 镜像 (3)Docker 容器的隔离性 - 使用 ...

  8. [Python设计模式] 第27章 正则表达式——解释器模式

    github地址:https://github.com/cheesezh/python_design_patterns 解释器模式 解释器模式,给定一个语言,定一个它的文法的一种表示,并定一个一个解释 ...

  9. Effective Java 第三版——89. 对于实例控制,枚举类型优于READRESOLVE

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  10. Centos7.4修改主机名HostName颜色及格式

    一.打开 .bashrc文件 1.位置:~(cd ~)目录下 2.cat .bashrc 原文件内容如下: # .bashrc # User specific aliases and function ...