白话Spring(基础篇)---AOP(实例篇-2)

本文详细介绍了在Spring框架中,如何仅针对类中的特定方法进行AOP切面处理,包括创建自定义切点、配置通知类型及其作用范围、修改接口及其实现类以实现拦截等功能,并通过实例演示了实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[一知半解,就是给自己挖坑]

在AOP(实例篇-1)中,我们演示了针对某个类对象的全部方法进行AOP切面处理,接下来,我们来演示一下,如何在一个类对象中,只针对某个方法进行AOP切面处理。

准备工作:

a.操作系统:win7 x64

b.开发工具:eclipse mars j2ee版本,maven3.3.2,Spring 4,junit4.12

c.工程仍然是上一个Spring091。

-------------------------------------------------------------------------------------------------------------------------------------

1.创建Pointcut.java文件,具体内容如下:

package com.java.ingo.point;

import java.lang.reflect.Method;
import org.springframework.aop.support.NameMatchMethodPointcut;
/**
*@author 作者 E-mail:ingo
*@version 创建时间:2016年3月4日上午11:43:23
*类说明
*/
public class Pointcut extends NameMatchMethodPointcut {

    private static final long serialVersionUID = 3990456017285944475L;
    @SuppressWarnings("rawtypes")
    public boolean matches(Method method, Class targetClass) {
        // 设置单个方法匹配
        this.setMappedName("delete");
        // 设置多个方法匹配
        String[] methods = { "delete","modify" };
        //也可以用“ * ” 来做匹配符号
        // this.setMappedName("get*");
        this.setMappedNames(methods);
        return super.matches(method, targetClass);
    }
}
2.修改beans.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"
	xmlns:context="http://www.springframework.org/schema/context"
	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/context     
          http://www.springframework.org/schema/context/spring-context-3.0.xsd 
          http://www.springframework.org/schema/aop     
          http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
	default-autowire="byName">

	<!-- ==============================利用spring自己的aop配置================================ -->
	<!-- 声明一个业务类 -->
	<bean id="baseBusiness" class="com.java.ingo.service.impl.BaseBusiness" />
	<!-- 声明通知类 -->
	<bean id="baseBefore" class="com.java.ingo.advice.BaseBeforeAdvice" />
	<bean id="baseAfterReturn" class="com.java.ingo.advice.BaseAfterReturnAdvice" />
	<bean id="baseAfterThrows" class="com.java.ingo.advice.BaseAfterThrowsAdvice" />
	<bean id="baseAround" class="com.java.ingo.advice.BaseAroundAdvice" />
	<!-- 指定切点匹配类 -->
	<bean id="pointcut" class="com.java.ingo.point.Pointcut" />

	<!-- 前置通知-->
	<bean id="matchBeforeAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="pointcut">
			<ref bean="pointcut" />
		</property>
		<property name="advice">
			<ref bean="baseBefore" />		
		</property>
	</bean>
	
	<!-- 后置通知-->
	<bean id="matchAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="patterns">  
         <list>  
           <value>.*delete</value>  
         </list>  
      </property>  
		<property name="advice">
			<ref bean="baseAfterReturn" />		
		</property>
	</bean>
	
	<!-- 环绕通知-->
	<bean id="matchAroundAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="mappedNames">  
        <list>  
          <value>delete</value>  
        </list>  
      </property> 
		<property name="advice">
			<ref bean="baseAround" />		
		</property>
	</bean>
	
	<!-- 使用ProxyFactoryBean 产生代理对象 -->
	<bean id="businessProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<!-- 代理对象所实现的接口 ,如果有接口可以这样设置 -->
		<property name="proxyInterfaces">
			<value>com.java.ingo.service.IBaseBusiness</value>
		</property>

		<!-- 设置目标对象 -->
		<property name="target">
			<ref local="baseBusiness" />
		</property>
		<!-- 代理对象所使用的拦截器 -->
		<property name="interceptorNames">
			<list>
				<value>matchBeforeAdvisor</value>
				<value>matchAfterAdvisor</value>
				<value>matchAroundAdvisor</value>
			</list>
		</property>
	</bean>
</beans>
我们来看看配置文件中各个配置项的含义:

a.首先,我们先定义了需要我们加入AOP的对象,设置id为baseBusiness。

b.接着,定义了4个不同类型的通知,通知分别继承于AOP接口,具体内容请查看前文详情

c.然后,我们分别定义了通知类型的作用范围,注意观察每一种通知范围的配置方式。

d.最后,设置ProxyFactoryBean。具体解释请查看代码中的注释部分


3.修改IBaseBusiness.java文件,具体内容如下:

package com.java.ingo.service;

import com.java.ingo.entity.Customer;
/**
*@author 作者 E-mail:ingo
*@version 创建时间:2016年3月5日上午10:40:25
*类说明
*/
public interface IBaseBusiness {

    public void delete(Customer obj);

    public String add(String obj);

    public void modify(Customer customer);

}

4.修改BaseBusiness.java,具体内容如下:

public class BaseBusiness implements IBaseBusiness {

    /**
     * 切入点
     */
    public void delete(Customer obj) {
        System.out.println("||///////////////////||");
        System.out.println("删除用户:"+obj.getName());
        System.out.println("||///////////////////||");
    }

    public String add(String add) {
    	System.out.println("||///////////////////||");
        System.out.println("add用户:"+add);
        System.out.println("||///////////////////||");
        return add;
    }

    public void modify(Customer obj) {
    	  System.out.println("|///////////////////||");
          System.out.println("modify用户:"+obj.getName());
          System.out.println("|///////////////////||");
    }

}

5.测试方法:运行main方法,分别执行接口中提供的三种方法,观察控制台输出即可。

-------------------------------------------------------------------------------------------------------------------------------------

备注:

1.后置通知中拦截规则:

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

2.环绕通知通的拦截规则:

环绕通知中可以用*通配符,如,*User就代表所有以User结尾的方法。注意这儿只匹配方法名,不会管类名和包名了。

-------------------------------------------------------------------------------------------------------------------------------------

至此,白话Spring(基础篇)---AOP(实例篇-2)结束。

参考资料:

Spring官网:http://spring.io/docs

其他博文:

http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example

http://tonl.iteye.com/blog/1966075


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值