`

应用Spring AOP(二)-------通过Advisor指定切入点

阅读更多

       上一篇日志使用的前置通知,后置通知,环绕通知和异常通知可以很好的拦截方法,并插入相应的代码。但是却存在一个问题,就是Spring AOP拦截了目标类中的所有方法。而在通常情况下,只需要拦截部分方法,比如只需要拦截目标类中方法名以set开始的所有方法。Spring AOP提供了Advisor和PointcutAdvisor来达到这个目的。

       常用的PointAdvisor有三种,DefaultPointcutAdvisor , RegexpMethodPointcutAdvisor 和 NameMatchMethodPointcutAdvisor,它们都在org.springframework.aop.support包中。由它们的名字可以看出,RegexpMethodPointcutAdvisor是通过正则表达式来匹配拦截的方法,NameMatchMethodPointcutAdvisor通过直接指定那些方法是需要拦截的,它也可以用*作为通配符。DefaultPointcutAdvisor则需要自定义切入点类。

       在上一篇日志的工程基础上的示例工程代码:

 结构没多少差别,就是com.aop包中多了一个MyPointcut类。当然applicationContext.xml文件内容也变化了,内容如下:

<?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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	
	<bean id="myUserService" class="com.service.UserService"></bean>
	
	<!-- 定义前置通知 -->
    <bean id="beforeLogAdvice" class="com.aop.BeforeLogAdvice"></bean>
    <bean id="beforePointcut" class="com.aop.MyPointcut"></bean>
    <bean id="myAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
      <property name="pointcut">
          <ref local="beforePointcut"/>
      </property>
      <property name="advice">
          <ref local="beforeLogAdvice"/>
      </property>
    </bean>
    
    <!-- 定义后置通知 -->
	<bean id="afterLogAdvice" class="com.aop.AfterLogAdvice"></bean>
	<bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
      <property name="patterns">
         <list>
           <value>.*deleteUser</value>
         </list>
      </property>
      <property name="advice">
          <ref local="afterLogAdvice"/>
      </property>
    </bean>
	
	<!-- 定义环绕通知 -->
	<bean id="logAroundAdvice" class="com.aop.LogAroundAdvice"></bean>
    <bean id="myAroundAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">  
      <property name="mappedNames">
        <list>
          <value>*User</value>
        </list>
      </property>
      <property name="advice">
        <ref local="logAroundAdvice" />
      </property>
    </bean>
	
	<!-- 定义异常通知 -->
	<bean id="throwsLogAdvice" class="com.aop.ThrowsLogAdvice"></bean>
    
	
    <!-- 定义代理类,名 称为myProxy,将通过myProxy访问业务类中的方法 -->
	<bean id="myProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
	  <property name="proxyInterfaces">
	    <value>com.service.IUserService</value>
	  </property>
	  <property name="interceptorNames">
	    <list>	     
	     <value>myAdvisor</value>
	     
	     <value>regexpAdvisor</value>
	     
	     <value>myAroundAdvisor</value>
	     
	     <value>throwsLogAdvice</value>
	    </list>
	  </property>
	  <property name="target" ref="myUserService"></property>
	</bean>
</beans>

对比上一个工程applicationContext.xml文件的内容,id为myProxy的bean里的interceptorNames拦截器名的list下不再是四个通知了。前置通知,后置通知和环绕通知都变成了Advisor。下面挨个来看。

 

首先看前置通知:

<!-- 定义前置通知 -->
    <bean id="beforeLogAdvice" class="com.aop.BeforeLogAdvice"></bean>
    <bean id="beforePointcut" class="com.aop.MyPointcut"></bean>
    <bean id="myAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
      <property name="pointcut">
          <ref local="beforePointcut"/>
      </property>
      <property name="advice">
          <ref local="beforeLogAdvice"/>
      </property>
    </bean>

 这里自定义了一个MyPointcut切入点类:

package com.aop;

import java.lang.reflect.Method;

import org.springframework.aop.support.NameMatchMethodPointcut;

public class MyPointcut extends NameMatchMethodPointcut {

	public boolean matches(Method method, Class targetClass) {
		this.setMappedName("addUser");
		//this.setMappedName("*User");
		return super.matches(method, targetClass);
	}
}

        Spring AOP在调动目标类的每一个方法之前,都会调用这里的matches方法来判断是否应该拦截该方法,当matches方法返回true时,表明当前方法应该被拦截。如果要想指定被拦截的方法,需要调用NameMatchMethodPointcut的setMappedName方法。本例中指定了addUser方法。当然也可以使用*作为通配符。如代码中的注释,this.setMappedName("*User")将会拦截以User结尾的所有方法。

        要想使用自定义的这个Pointcut类,必须装配DefaultPointcutAdvisor,即applicationContext.xml中id为myAdvisor的bean。这个bean中的pointcut属性指定了切入点,advice属性指定了通知。

 

再来看看后置通知:

<!-- 定义后置通知 -->
	<bean id="afterLogAdvice" class="com.aop.AfterLogAdvice"></bean>
	<bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
      <property name="patterns">
         <list>
           <value>.*deleteUser</value>
         </list>
      </property>
      <property name="advice">
          <ref local="afterLogAdvice"/>
      </property>
    </bean>

 这里用到了RegexpMethodPointcutAdvisor。bean下的patterns属性下添加一些正则表达式规则,能够匹配这些规则的方法就会被拦截。值得一提的是,这儿匹配的是方法的完整路径,包括类名已经类的包名。回顾一下,这儿的目标类是com.service.UserService,它里面只有两个方法addUser和deleteUser。这两个方法的完整路径就是com.service.UserService.addUser 和  com.service.UserService.deleteUser 。这儿写的正则表达式是.*deleteUser ,明显它可以匹配com.service.UserService.deleteUser,所以这个方法会被拦截。假设将正则表达式写成deleteUser,那么它不能匹配com.service.UserService.deleteUser 这整个字符串,所以讲不会起作用。如果要拦截方法名中包含abc的方面,正则表达式写成.*abc.*就可以了(当然包名和类名不能是abc啦)。

 

最后看看环绕通知:

<!-- 定义环绕通知 -->
	<bean id="logAroundAdvice" class="com.aop.LogAroundAdvice"></bean>
    <bean id="myAroundAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">  
      <property name="mappedNames">
        <list>
          <value>*User</value>
        </list>
      </property>
      <property name="advice">
        <ref local="logAroundAdvice" />
      </property>
    </bean>

 这里用到了NameMatchMethodPointcutAdvisor,它的mappedNames属性下添加想要拦截的方法名就可以了,当然也可以用*通配符啦,*User就代表所有以User结尾的方法。注意这儿只匹配方法名,不会管类名和包名了。

 

工程代码在附件中。。。。

  • 大小: 15.6 KB
分享到:
评论

相关推荐

    aopalliance-1.0.jar下载

    1. Advisor接口:Advisor是AOP的核心概念,它封装了Pointcut(切入点)和Advice(通知)。一个Advisor可以识别何时应用特定的Advice,并决定在何处应用。 2. Pointcut接口:Pointcut是程序执行中的一个特定点,如...

    Spring AOP实现机制

    - 在`&lt;aop:config&gt;`标签内定义切面,`&lt;aop:pointcut&gt;`定义切入点,`&lt;aop:advisor&gt;`定义通知。 - `&lt;aop:aspect&gt;`标签用于定义完整的切面,包括切入点和通知。 - **注解配置**: - 使用`@Aspect`注解定义切面类,`...

    spring Aop文档

    1. **基于XML的配置**:通过在Spring配置文件中声明切面、切入点和通知来实现。 2. **基于注解的方式**:使用`@AspectJ`风格的注解来声明切面和通知。 #### 四、Spring AOP 的配置示例 下面是一个简单的基于注解的...

    spring2-aop.pdf

    - **切入点 (Pointcut)**:定义切面应该应用于哪些连接点的规则。 - **增强 (Advice)**:描述在指定连接点发生时应执行的操作。 - **引入 (Introduction)**:为被通知类添加新的接口实现。 - **增强器/切面封装 ...

    spring aop 五个依赖jar

    使用Spring AOP,开发者可以定义切面,声明切入点(即关注点的定位),编写通知(即实际的增强代码),并通过配置将它们应用到目标对象上。这样,我们可以保持业务逻辑的清晰,同时实现系统级的服务,如事务管理、...

    Spring AOP 拦截器 Advisor

    在 `inactive-aop.xml` 配置文件中,我们可以通过 `&lt;aop:config&gt;` 和 `&lt;aop:advisor&gt;` 标签来声明和配置这个 Advisor,指定其切入点表达式。 总的来说,Spring AOP 拦截器 Advisor 是一种强大的工具,它允许我们在...

    AOP.rar-Spring-AOP源码Demo

    - **`org.springframework.aop.aspectj.AspectJExpressionPointcut`**:实现切入点表达式的解析和匹配。 - **`org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAdvisorFactory`**:处理基于...

    spring aop必须jar包

    在Spring的XML配置文件中,可以通过`&lt;aop:config&gt;`元素开启AOP,并通过`&lt;aop:pointcut&gt;`定义切入点,`&lt;aop:advisor&gt;`或`&lt;aop:aspect&gt;`定义切面。此外,还可以使用注解方式来声明切点和切面,如`@Aspect`、`@Pointcut...

    springAop的配置实现

    - `&lt;aop:advisor&gt;`:定义通知和切入点的关联,指定何时何地执行通知。 - `&lt;aop:aspect&gt;`:定义切面,包括其通知和切入点。 - `&lt;aop:before&gt;`、`&lt;aop:after&gt;`、`&lt;aop:around&gt;`等:分别用于定义不同类型的通知。 **5....

    spring AOP入门教程

    4. **切入点(Pointcut)**:定义一组连接点的表达式,用于指定通知何时应用。 5. **织入(Weaving)**:将切面应用到目标对象以创建新的代理对象的过程,可以在编译时、类加载时或运行时进行。 ### 三、Spring AOP...

    spring2-aop入门实例教程

    - **增强器/切面封装(Advisor)**:封装了切入点和通知,是Spring AOP中的基本单位。 - **ProxyFactoryBean**:Spring AOP中的代理工厂Bean,用于创建代理对象。 #### 六、实战示例:模拟Warcraft游戏 - **示例简介*...

    Spring AOP框架实现的结构分析

    切入点是一组连接点的总称,用于指定某个增强应该在何时被调用。 增强是指在特定连接点执行的动作。许多 AOP 框架都以拦截器的形式来表现增强--所谓拦截器是这样的一个对象:当连接点被调用时,它会收到一个回调...

    spring aop所需jar包

    - XML配置:在Spring配置文件中定义切面、通知和切入点。 - 注解配置:使用`@EnableAspectJAutoProxy`开启基于注解的AOP支持,并在类上使用`@Aspect`定义切面。 - 自动代理:Spring会根据配置自动生成代理对象,...

    aopalliance-1.0 jar包

    Advisor通常包含一个Pointcut(切入点)和一个对应的Advice。 在实际开发中,aopalliance-1.0.jar常作为Spring框架的一部分使用,因为Spring AOP就是基于AOP Alliance的接口实现的。Spring框架通过使用AOP Alliance...

    spring aop管理xml版

    在实际应用中,我们会在`&lt;bean&gt;`元素中定义切面类,并在`&lt;aop:config&gt;`中通过`&lt;aop:aspect&gt;`元素引用它,然后定义相应的通知和切入点。例如: ```xml &lt;aop:config&gt; &lt;aop:aspect id="loggingAspect" ref="logging...

    SpringAop学习笔记以及实现Demo

    3. **基于XML配置的AOP**:在Spring的配置文件中,可以通过`&lt;aop:config&gt;`、`&lt;aop:advisor&gt;`、`&lt;aop:pointcut&gt;`等标签定义切面、通知和切入点。 ### 三、Spring AOP实战 1. **经典代理模式**:通过JDK动态代理或...

    spring-aop

    - **切点(Pointcut)**:定义了通知应该在哪些方法上应用,可以通过切入点表达式来指定,如`execution(* com.example.service.*.*(..))`表示匹配com.example.service包下的所有方法。 - **通知(Advice)**:在切点...

    SPRING:aspect和advisor区别

    - 这个例子展示了如何定义一个事务顾问`txAdvice`,并通过`&lt;aop:advisor&gt;`标签将其与切入点`busServiceMethods`关联起来。这表示所有符合该切入点定义的方法调用都将受到事务控制。 #### 四、Aspect与Advisor之间...

Global site tag (gtag.js) - Google Analytics