Spring AOP 剖析(6)

Spring AOP 的底层实现机制

 

 

 

2.  Spring AOP 中的 Pointcut

 

6.  扩展 Pointcut

 

如何前面的 Pointcut 类型都无法满足要求,这种情况下可以扩展 Spring AOP 的 Pointcut ,给出自定义的 Pointcut。

 

要自定义 Pointcut ,Spring AOP 已经提供了相应的扩展抽象支持,我们只需要继承相应的抽象父类,然后实现或者覆写

 

方法逻辑即可。

 

Spring AOP 的 Pointcut 类型可以划分为  StaticMethodMatcherPointcut 和 DynamicMethodMatcherPointcut

 

自定义 Pointcut 只需要在这两个抽象类的基础上实现相应子类即可。

 

 


a. StaticMethodMatcherPointcut

 

package org.springframework.aop.support;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;

/**
 * 因为是 StaticMethodMatcher,所以其 MethodMatcher 的 isRuntime 方法返回 false,
 * 同时三个参数的 matches 方法抛出 UnsupportedOperationException 异常,
 * 以表示该方法不应该被调用到。(该部分在 抽象父类 StaticMethodMatcher 中实现)
 *
 */
public abstract class StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut {

	private ClassFilter classFilter = ClassFilter.TRUE;


	/**
	 * 默认子类的 ClassFilter 均为 ClassFilter.TRUE,即忽略类的类型匹配。
	 */
	public ClassFilter getClassFilter() {
		return this.classFilter;
	}
	
	/**
	 * 如果子类需要对目标对象的类型做进一步的限制,可以通过该方法设置相应的 ClassFilter 实现
	 * @param classFilter
	 */
	public void setClassFilter(ClassFilter classFilter) {
		this.classFilter = classFilter;
	}

	public final MethodMatcher getMethodMatcher() {
		return this;
	}

}

 

最终实现 自定义的StaticMethodMatcherPointcut 只需要实现两个参数的 matches 方法即可。

 

例如:提供一个 Pointcut , 用来扑捉系统中数据访问对象中的查询方法。

 

package prx.aop.pointcut;

import java.lang.reflect.Method;

import org.springframework.aop.support.StaticMethodMatcherPointcut;

public class QueryMethodPointcut extends StaticMethodMatcherPointcut {

	public boolean matches(Method method, Class<?> targetClass) {
		return method.getName().startsWith("query") 
				&& targetClass.getPackage().getName().contains("dao");
	}

}

 

b. DynamicMethodMatcherPointcut

 

package org.springframework.aop.support;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;

/**
 * 因为是 DynamicMethodMatcher,所以其 MethodMatcher 的 isRuntime 方法返回 true,
 * 同时两个参数的 matches 也返回 true,以便三个参数的方法顺利执行
 * (该部分在 抽象父类 DynamicMethodMatcher 中实现)
 */
public abstract class DynamicMethodMatcherPointcut extends DynamicMethodMatcher implements Pointcut {

	/**
	 * 默认子类的 ClassFilter 均为 ClassFilter.TRUE,即忽略类的类型匹配。
	 * 如果需要特定的目标对象类型限定,需要覆盖这个方法。
	 */
	public ClassFilter getClassFilter() {
		return ClassFilter.TRUE;
	}

	public final MethodMatcher getMethodMatcher() {
		return this;
	}

}

 

最终实现自定义的 DynamicMethodMatcherPointcut 只需要实现三个参数的 matches 方法即可。

 

例如:有个查询只有 Boss 才能访问。

 

package prx.aop.pointcut;

import java.lang.reflect.Method;

import org.springframework.aop.support.DynamicMethodMatcherPointcut;

public class BossQueryMethodPointcut extends DynamicMethodMatcherPointcut {

	public boolean matches(Method method, Class<?> targetClass, Object[] args) {
		if(method.getName().startsWith("query") 
				&& targetClass.getPackage().getName().contains("dao")) {
			if(args != null && args.length > 1) {
				return "Boss".equals(args[0]);
			}
		}
		return false;
	}

}

 

如果愿意,也可以覆盖 两个参数的 matches 方法,这样,不用每次都得到三个参数的 matches 方法执行的时候才检查

 

所有的条件。

 


将 Pointcut 加入 IoC 容器中

 

选择好了 Pointcut ,剩下就是 将它们加入Spring IoC 容器中,以便 Spring 管理。 Spring 中的 Pointcut 实现都是

 

普通的 Java 对象, 所以想普通的 POJO 那样配置注入就可以了。

 

<bean id="nameMatchPointcut" class="org.springframework.aop.support.NameMatchMethodPointcut">
	<property name="mappedNames">
		<list>
			<value>methodName1</value>
			<value>methodName2</value>
		</list>
	</property>
</bean>
 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值