`
让往事都随风
  • 浏览: 67163 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

Spring AOP 使用通知者和切入点

阅读更多
首先回想一下,之前我们所给出的所有例子都是通过拦截所有的方法调用来完成AOP的实现的。但是我们会遇到两个问题:
我们如何只让某一个或者某一类的方法调用被AOP钩到(hook)而不是所有的方法,从而提高效率?
我们如何不用通过必须在AOP逻辑中硬编码方法名称列表的方式,去检测方法名称,从而找到正确的方法?

对于第一个问题,因为Spring会对不需要被AOP逻辑处理的方法进行优化,而ProxyFactory内部的实现是将所有方法调用交给DefaultPointcutAdvisor来处理,而后者则将AOP拦截设定为“所有方法调用”,这样会大大降低性能。

对于第二个问题,通过硬编码的方式,使用if之类的语句去判断AOP逻辑中调用的是否是正确的方法,显然的,首先重用性会大打折扣,其次,对性能也会有一定的拖累。
那么如何解决以上两个问题呢?答案就是使用通知者和切入点。

Spring中的通知者一共有4个(如果你的Spring不止4个,那么也许是版本更新的缘故吧),但是在Spring AOP基础部分,我们只使用最基本的DefaultPointcutAdvisor来做示例。前面说过Spring中一个Advisor就代表了一个切面,它包含了AOP逻辑(各种通知)和切入点(本文这部分的重点Pointcut接口及其实现)。而DefaultPointcutAdvisor,就是Spring面向切面编程所实现的最简单的类,我们以后在基础部分只使用而不介绍。

那么切入点,很简单,重复强调在Spring中就是方法调用的集合。但是,您是否要使用切入点编程,还要取决于另外一个因素——目标类亲和度。

参考《学习笔记》(十三)中最后部分给出关于验证弱密钥那部分的代码。像这种AOP逻辑与其它的类关系结合紧密的情况,我们称之“目标类亲和度”高,显然,对于这种情况,我们最好不使用切入点编程来处理。然而,大多数情况下,亲和度很低或者干脆没有,那么要坚持使用切入点编程不动摇!

切入点相关接口

说了这么多废话,切入点到底是什么?那么马上就来看看Spring中关于切入点编程的三个重要接口吧!

1。Pointcut接口

Spring中,要创建切入点,就必须要实现Pointcut(切入点)接口。
其中两个主要方法:ClassFilter getClassFilter()和MethodMatcher getMethodMatcher()。二者返回类型显而易见。

getClassFilter()

作用:Spring AOP在确定某个Pointcut是否适用于某个方法时,它首先会用getClassFilter()方法返回的ClassFilter(类过滤器)类实例的相关方法来测试被AOP所截获的方法调用是否来自正确的类。

解释:假如两个类A和B都有相同签名的方法public void operation(int arg),而且这两个类都需要应用到AOP当中去,而我们只希望某个AOP逻辑中使用的是B类的operation(),怎么判定到底是哪个类的operation被调用了呢?您一定已经猜到了,就是通过这个ClassFilter实例的方法来判断的。

getMethodMatcher()

作用:用来检测被Spring AOP所拦截到的方法是否是目标类的正确方法

解释:如果一个类A,有n个operation()方法重载。那么具体是哪个operation()方法被调用了,这个时候Spring AOP就要使用MethodMatcher(方法匹配器)类实例的相关方法去测试了。

2。ClassFilter接口

作用:见Pointcut接口getClassFilter()解释部分
实现:仅仅定义了一个接口

boolean matches(Class clazz)
顾名思义,如果切入点适合目标类,那么(Spring AOP的具体实现中)返回true,否则返回false

3。MethodMatcher接口

作用:见Pointcut接口getMethodMatcher()解释部分

实现:有三种主要方法

boolean isRuntime()
boolean matches(Method m, class targetClass)
boolean matches(Method m, Class targetClass, Object[] args)

方法isRuntime()的返回值为Spring决定了一个MethodMatcher的实例是静态的还是动态的。在Spring使用一个MethodMatcher之前,首先会调用它的isRuntime()方法,如果返回值为false,那么该MethodMatcher实例就是静态的,否则就是动态的。

如果是静态的MethodMatcher实例,Spring会对目标类上的每个方法调用一次MethodMatcher的matches(Method m, class targetClass)方法,返回值会被存放起来以便以后使用。这样对每个方法是否是需要AOP的适用性测试只会进行一次,之后目标类的某个方法被调用时就不会再调用matches()方法了。显而易见,静态的MethodMatcher效率比较高,但是缺乏一定的灵活性。

如果是动态的MethodMatcher,仍然会首先执行matches(Method m, class targetClass)进行测试,但是如果目标类的某个方法使得(matches(Method, Class)方法的)返回值是true的话,那么以后在目标类的这个方法被调用时,Spring会再调用boolean matches(Method m, Class targetClass, Object[] args)方法来进一步价差方法调用是否正确。显而易见,动态的MethodMatcher会更灵活,可以根据一次具体的方法调用而不是方法本身,来决定切入点是否适用,但是性能要低于静态的MethodMatcher。

以上三个接口是实现Spring切面编程的基础,当然我们可以自己实现他们创造出我们自己的切面类,但是这样比较麻烦而且不是必须。事实上Spring AOP框架已经为我们提供好了相应的实现。这些实现能够很好的满足我们的日常需求,如果不够怎么办?AspectJ呗!

Spring提供的实现一共有七种(七剑?别忘了Spring版本不同,数量可能不同),分别是:
DynamicMethodMatcherPointcut(动态方法匹配器切入点)
StaticMethodMatcherPointcut(静态方法匹配器切入点)
NameMethodMatcherPointcut(名称匹配器方法切入点)
JdkRegexpMethodPointcut(JDK正则表达式方法切入点)
Perl5RegexpMethodPointcut(支持Perl5的正则表达式方法切入点)
ComposablePointcut(可组合切入点)
ControlFlowPointcut(控制流程切入点)
分享到:
评论

相关推荐

    Spring AOP 16道面试题及答案.docx

    总的来说,Spring AOP通过代理和通知机制,实现了横切关注点的模块化,使得业务逻辑与系统服务(如日志、事务等)解耦,提高了代码的可读性和可维护性。同时,引介功能进一步增强了切面的功能,可以为对象动态地添加...

    使用切入点匹配方法实现Spring AOP环绕通知

    本篇将详细探讨如何使用切入点匹配方法实现Spring AOP的环绕通知。 首先,理解AOP的核心概念: 1. 切面(Aspect):切面是关注点的模块化,它封装了横切关注点,如日志、事务等。 2. 连接点(Join Point):程序...

    JavaEE Spring AOP使用

    2. **XML配置的AOP**:在传统的Spring配置中,我们需要在`<aop:config>`元素内定义切面、切入点和通知。虽然相比注解方式繁琐,但在某些情况下更具有灵活性。 压缩包中的`SpringAOPTest`可能包含了一个Spring AOP的...

    简单spring aop 例子

    1. **定义切面(Aspect)**:切面是包含通知(Advice)和切入点(Pointcut)的类。通知定义了要执行的逻辑,切入点定义了何时执行。例如,我们可以创建一个名为`LoggingAspect`的类,包含一个`@Before`通知来记录...

    Spring AOP实现机制

    - `<aop:aspect>`标签用于定义完整的切面,包括切入点和通知。 - **注解配置**: - 使用`@Aspect`注解定义切面类,`@Pointcut`定义切入点方法,`@Before`、`@After`、`@Around`等定义不同类型的通知。 ### 5. ...

    Spring AOP面向方面编程原理:AOP概念

    4. **丰富的切入点表达式语言**:Spring AOP支持使用SpEL(Spring Expression Language)来定义复杂的切入点表达式,这让开发者能够更加灵活地控制通知的触发条件。 #### 四、Spring AOP的实现示例 接下来,我们...

    spring之AOP(动态代理)

    AOP的核心概念是切面、通知、连接点、切入点和织入。在Spring中,AOP主要通过两种动态代理技术实现:JDK动态代理和CGLIB动态代理。 首先,让我们详细了解一下JDK动态代理。JDK动态代理基于Java的接口实现,它适用于...

    spring AOP注解的应用1

    本篇主要探讨的是如何利用Spring AOP的注解来实现这些功能,包括前置通知、后置通知、返回通知和异常通知。 ### 前置通知(Before通知) 前置通知在目标方法执行之前运行。在Spring AOP中,我们使用`@Before`注解...

    spring的AOP和AOP相关概念切入点表达式写法详细说明.emmx

    使用mindmaster打开

    Spring AOP简单demo

    2. **XML配置驱动**:在Spring配置文件中定义切面、通知和切入点表达式。 **Spring AOP示例** 以入门级的`advice`为例,我们可能有一个简单的日志切面: ```java @Aspect @Component public class LoggingAspect ...

    SpringAop xml方式配置通知

    在Spring中,我们可以通过XML配置文件来定义切面、切入点和通知。以下是一个基本的XML配置示例: ```xml <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi=...

    springAop的配置实现

    Spring AOP通过XML配置文件提供了灵活的方式来定义和管理切面、切入点和通知,使得我们可以轻松地在应用程序中实现横切关注点的解耦。了解和掌握Spring AOP的配置实现,有助于提升我们构建松散耦合、易于维护的系统...

    spring AOP的运用

    2. XML配置:在Spring配置文件中定义切面、通知和切入点表达式。 下面,我们通过源码分析Spring AOP的工作流程: 1. 当Spring容器启动时,会扫描所有带有`@Aspect`注解的类,并将其转换为对应的`...

    spring AOP入门教程

    1. **切面(Aspect)**:切面是封装了横切关注点的模块,它包含通知(advice)和切入点(pointcut)。 2. **通知(Advice)**:在特定的连接点(Join Point)执行的代码,如方法调用前后、异常发生时等。 3. **连接...

    spring aop 五个依赖jar

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

    springaop.zip

    总的来说,"springaop.zip" 提供了一个学习Spring AOP的实践案例,通过XML配置实现切面、通知和切入点的定义,有助于加深对面向切面编程的理解和应用。结合配套的博客文章,可以系统地学习如何在Spring环境中有效地...

    spring aop的demo

    在`springAop1`这个压缩包中,可能包含了一个简单的应用示例,展示了如何定义一个切面类,以及如何在该类中定义通知方法。例如,我们可能会看到一个名为`LoggingAspect`的类,其中包含了`@Before`注解的方法,用于在...

    spring-aop实例

    4. **切入点表达式(Pointcut Expression)**:这是定义切点的语法,使用了AspectJ的表达式语言,可以精确地定位到需要应用通知的代码位置。 5. **代理(Proxy)**:Spring AOP通过动态代理机制创建目标对象的代理...

    spring-aop-jar

    - 切入点(Pointcut):切入点是连接点的集合,定义了切面将在哪些连接点上应用。 - 通知(Advice):通知是在特定连接点执行的代码,比如在方法调用前后执行的代码。 - 代理(Proxy):Spring AOP通过代理来实现切...

Global site tag (gtag.js) - Google Analytics