| « | November 2025 | » | | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | | | | | | | |
| 公告 |
戒除浮躁,读好书,交益友 |
| Blog信息 |
|
blog名称:邢红瑞的blog 日志总数:523 评论数量:1142 留言数量:0 访问次数:9732386 建立时间:2004年12月20日 |

| |
|
[java语言]深入浅出 spring AOP (六) 原创空间, 软件技术
邢红瑞 发表于 2006/1/3 14:28:21 |
|
前面的几个例子都是拦截所有类的所有方法,但是我们主要是拦截某些类的某些方法,使用Pointcut可以做到。pointcut是一系Joinpoint的集合,它定义了需要注入advice的位置。AOP框架必须允许开发者指定切入点,advisor是pointcut和advice的装配器,是将advice织入预定义位置的代码中。 Pointcut的定义public interface Pointcut { ClassFilter getClassFilter (); MethodMatcher getMethodMatcher();}Pointcut interface只有两个方法,返回ClassFilter and MethodMatcher的实例。ClassFilter接口被用来将切入点限制到一个给定的目标类的集合。 如果matches()永远返回true,所有的目标类都将被匹配。 public interface ClassFilter {
boolean matches(Class clazz);}MethodMatcher接口如下:
public interface MethodMatcher {
boolean matches(Method m, Class targetClass);
boolean isRuntime();
boolean matches(Method m, Class targetClass, Object[] args);}matches(Method, Class) 方法被用来测试这个切入点是否匹 配目标类的给定方法。这个测试可以在AOP代理创建的时候执行,避免在所有方法调用时都需要进行 测试。如果2个参数的匹配方法对某个方法返回true,并且MethodMatcher的 isRuntime()也返回true,那么3个参数的匹配方法将在每次方法调用的时候被调用。这使切入点能够在目标通知被执行之前立即查看传递给方法调用的参数。
大部分MethodMatcher都是静态的,意味着isRuntime()方法 返回false。这种情况下3个参数的匹配方法永远不会被调用。如果可能,尽量使用静态切入点。spring提供Pointcut interface的7种实现,详见它的文档。
在使用Pointcut之前,必须先创建Advisor或指定PointcutAdvisor。一个advisor就是一个aspect的完整的模块化表示,一个advisor应该包括通知和切入点。Spring中很多内建的切入点都有对应的PointcutAdvisor,DefaultPointcutAdvisor 是最通用的advisor类,它可以和MethodInterceptor、 BeforeAdvice或者ThrowsAdvice一起使用。在应用较小时,只有很少类需要被切入时,ProxyFactoryBean 可以使用。当有许多类需要被切入时,为每个代理创建ProxyFactoryBean就显得很繁琐。可以通过容器来创建代理。Spring提供了两个类实现自动代理:BeanNameAutoProxyCreator和DefaultAdvisorAutoProxyCreator。BeanNameAutoProxyCreator为匹配名字的Bean产生代理,它可以使用在将一个或者多个aspect应用在命名相似的Bean中。自动代理框架假设代理将要暴露出什么接口。如果目标Bean没有实现任何接口,这时就会动态产生一个子类。最有效自动代理是DefaultAdvisorAutoProxyCreator,你只需要在BeanFactory中包含它的配置。他使用实现了BeanPostProcessor接口。在Bean定义被加载倒Spring容器中后,DefaultAdvisorAutoProxyCreator将搜索配置文件中的Advisor,最后它将Advisor应用到匹配Advisor切入点的Bean中。注意:这个代理只对Advisor起作用,它需要通过Advisor来得到需要通知的Bean。还有元数据自动代理(MetaData AutoProxy),元数据自动代理配置依赖于源代码属性而不是外部XML配置文件。这可以非常方便的使源代码和AOP元数据组织在同一个地方。元数据自动代理最常用的地方是用来声明事务。下面举个非常有用的例子,拦截DataSource的getConnection,用于查看数据连接的处理advisor类package com.tatan;
import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.Method;
public class MyAdvice implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable {
Object returnValue = invocation.proceed();
Method m = invocation.getMethod(); Object target = invocation.getThis(); Object[] args = invocation.getArguments(); System.out.println("Executed method: " + m.getName()); System.out.println("On object of type: " + target.getClass().getName()); if(args!=null) { for (int i=0;i<args.length;i++) { System.out.println("---->" + args[i]); } } return returnValue; }}
<bean id="myAdvice" class="com.tatan.MyAdvice"/>
<bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice"> <ref local="myAdvice"/> </property> <property name="mappedName"> <value>getConnection</value> </property> </bean>
<bean id="dataSourceProxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="interceptorNames"> <list> <value>myAdvisor</value> </list> </property> <property name="beanNames"> <list> <value>dataSource</value> </list> </property> </bean> |
|
|
回复:深入浅出 spring AOP (六) 原创空间, 软件技术
macrochen(游客)发表评论于2006/7/28 7:50:18 |
|
|
回复:深入浅出 spring AOP (六) 原创空间, 软件技术
macrochen(游客)发表评论于2006/7/28 6:48:22 |
| “在应用较小时,只有很少类需要被切入时,ProxyFactoryBean 可以使用。当有许多类需要被切入时,为每个代理创建ProxyFactoryBean就显得很繁琐。”
这里应该有些出入,不是为每个代理创建ProxyFactoryBean,而是创建Advisor |
|
|
回复:深入浅出 spring AOP (六) 原创空间, 软件技术
xiaoxiao(游客)发表评论于2006/5/31 16:18:19 |
|
» 1 »
|