- Spring 2.5 Aspect Oriented Programming
- Massimiliano Dessi
- 2242字
- 2021-05-21 20:23:12
Pointcut
A pointcut is an expression for the selection of joinpoints. It can be a collection of joinpoints used to define an advice that has to be executed. By defining pointcuts you can have control of the objects composing the application, at the points where the advices are applied.
As Spring defines method invocation joinpoints, all the methods that can be invoked on a class will be joinpoints.
These are some examples of pointcuts:
- Methods starting with a certain prefix (such as,
getter
andsetter
) - Methods with a particular package (such as
org.springaop.domain.*
) - Methods that return a certain kind of output (such as
public MyClass get*(...)
) - Any combination of the previous three examples
Pointcut and its components
A pointcut is the composition of a ClassFilter
and a MethodMatcher
. A ClassFilter
narrows the matching of a pointcut or introduction to a given set of target classes, while a MethodMatcher
checks whether the target method is eligible for advice.
public interface Pointcut { public ClassFilter getClassFilter (); public MethodMatcher getMethodMatcher(); }
The getClassFilter
method is called first, to check if it can be applied to the class used.
The ClassFilter
interface that filters the classes is composed in this way:
public interface ClassFilter { public boolean matches(Class clazz); public static final ClassFilter TRUE = TrueClassFilter.INSTANCE; }
Using the constant ClassFilter TRUE
, we obtain a match for all classes.
In its implementation, it will return a Boolean value according to whether or not the input parameter belongs to the wanted type.
Then, the getMethodMatcher
method of the Pointcut
interface is called. The MethodMatcher
interface is composed in this way:
public interface MethodMatcher { boolean matches(Method m, Class targetClass); boolean isRuntime(); boolean matches(Method m, Class targetClass, Object[] args); }
The first method that's called is isRuntime()
. It tells Spring whether the MethodMatcher
is static or dynamic:
- If the result is false, it's a static
MethodMatcher
and Spring calls the methodmatches(Method, Class)
once for every method on the target class, caching the return value for subsequent invocations. - If the result is true, it's a dynamic
MethodMatcher
. Spring does a static check callingmatches(Method m, Class targetClass)
the first time to check the applicability. If the result is true, for every invocation thematches(Method m, Class targetClass, Object[] args)
is called.
In this way, the checkup is done only the first time, and the subsequent times the cached value is recovered. From this, we understand that unless we need the flexibility of having a dynamic MethodMatcher
, it's better to use the static one.
Spring provides pointcuts that are ready to use, so normally, there's no need to implement your pointcut. Pointcuts that are ready to use provided by Spring are:
NameMatchMethodPointcut
RegexpMethodPointcut
StaticMethodMatcherPointcut
DynamicMethodMatcherPointcut
Using the NameMatchMethodPointcut
method, you can create a pointcut that performs simple matching against a list of method names. This class is used for the programmatic creation of proxies, and for configurations in the Spring factory with Setter Injection.
The full qualified name of the NameMAtchMethodPointcut
class is:
org.springframework.aop.support.NameMatchMethodPointcut
The following methods are available:
NameMatchMethodPointcut addMethodName(String methodName)
void setMappedName(String methodName)
void setMappedNames(String methodName)
The two setter methods are used for Setter Injection. The addMethodName
method is used for the addition in a simple way of the names of the necessary methods. To allow calling addMethodName
several times to add all the required method names, this
is returned.
Pointcut pc = new NameMatchMethodPointcut().addMethodName("setStartDate").addMethodName("setEndDate");
Let us see an example that explains the usage of NameMatchMethodPointcut
.
The target class on which the advice is applied is shown as follows:
package org.springaop.chapter.two.pointcut; public class NameMethodTargetExample { public void printName(){ System.out.println("Max"); } public void printAction(){ System.out.println("runs"); } public void printSpot(){ System.out.println("in Poetto beach"); } }
The advice that contains the logic to be executed:
package org.springaop.chapter.two.pointcut; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class AdviceExample implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("Invoking " + invocation.getMethod().getName()); Object retVal = invocation.proceed(); System.out.println("Job Done"); return retVal; } }
The test class:
package org.springaop.chapter.two.pointcut; import org.springframework.aop.Advisor; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.NameMatchMethodPointcut; public class NameMethodMatcherExample { public static void main(String[] args) { NameMethodTargetExample target = new NameMethodTargetExample(); NameMatchMethodPointcut pc = new NameMatchMethodPointcut(); pc.addMethodName("printSpot"); pc.addMethodName("printAction"); Advisor advisor = new DefaultPointcutAdvisor(pc, new AdviceExample()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); NameMethodTargetExample proxy = (NameMethodTargetExample)pf.getProxy(); proxy.printName(); proxy.printAction(); proxy.printSpot(); } }
The result will be:

Let's try to see what happened. We defined a target class, an around advice that prints, before the invocation, the name of the invoked method. Subsequently, the method invokes on the target class, and after the invocation it prints Job Done.
To test NameMethodMatcher
, we'll write the NameMethodMatcherExample
class with a main method, then add to NameMatchMethodPointcut
only two of the three methods that could be matched by the pointcut.
Then we'll create an advisor that binds pointcut and advice, create a new ProxyFactory
to which we will set advisor and target object, and then invoke methods.
The result is that only the two added methods (printAction()
and printSpot()
) are intercepted by the pointcut, whereas printName()
is not intercepted.
To allow pointcuts in a more generic modality than the mere declaration of names, it's possible to use regular expressions.
For this purpose in Spring 1.x, Jakarta ORO (Perl5 regexp) is being used. If we want to use JDK 1.3; otherwise, we can use the regular expression provided by java.util.regex
if running on JDK 1.4
The full qualified name is:
org.springframework.aop.support.JdkRegexpMethodPointcut
The JdkRexepMethodPointcut
allows you to define pointcuts using JDK 1.4 regular expression support.
org.springframework.aop.support.Perl5RegexpMethodPointcut
The Perl5RegexpMethodPointcut
allows you to define pointcuts using Perl 5 regular expression syntax.
For their configuration, we use a single pattern or a list of patterns:
- 1
patterns
: Array of regular expressions for methods that the pointcut will match - 2
pattern
: Convenient String property when you have just a single pattern and don't need an array
In Spring 2.5, we have only the JdkRegexpMethodPointcut
, for JDK 1.4 or higher.
<bean id="settersAndHumorousPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="patterns"> <list> <value>.*get.*</value> <value>.*humorous</value> </list> </property> </bean>
If we use Spring 2.5 or 3.x and a JDK previous to 1.4, Jakarta ORO is used in the background, configuring an advisor in this way:
<bean id="settersAndHumorousAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="beanNameOfAopAllianceInterceptor"/> </property> <property name="patterns"> <list> <value>.*set.*</value> <value>.*humorous</value> </list> </property> </bean>
An example of RegexpMethodPointcut
use follows:
The target class on which to apply the advice:
package org.springaop.chapter.two.pointcut; public class RegExpTargetExample { public void printName(){ System.out.println("Max"); } public void printAction(){ System.out.println("swims"); } public void printSpot(){ System.out.println("in Poetto beach"); } }
The advice that contains the logic to be executed:
package org.springaop.chapter.two.pointcut; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class AdviceExample implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("Invoking " + invocation.getMethod().getName()); Object retVal = invocation.proceed(); System.out.println("Job Done"); return retVal; } }
The test class:
package org.springaop.chapter.two.pointcut; import org.springframework.aop.Advisor; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.JdkRegexpMethodPointcut; public class RegExpMethodMatcherExample { public static void main(String[] args) { RegExpTargetExample target = new RegExpTargetExample(); JdkRegexpMethodPointcut pc = new JdkRegexpMethodPointcut(); String[] patterns = {".*Spot.*",".*Action.*"}; pc.setPatterns(patterns); Advisor advisor = new DefaultPointcutAdvisor(pc, new AdviceExample()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); RegExpTargetExample proxy = (RegExpTargetExample)pf.getProxy(); proxy.printName(); proxy.printAction(); proxy.printSpot(); } }
The result will be:

Let's see what we have done. We defined a target class and an around advice that prints, before the invocation, the name of the invoked method. Subsequently, the method invokes on the target class, and after the invocation it prints Job Done. To test JdkRegexpMethodPointcut
we wrote the RegExpMethodMatcherExample
class with a main method. We set a string array with the patterns of regular expressions to JdkRegexpMethodPointcut
.
We created an advisor that bound pointcut and advice, created a new ProxyFactory
to which we set the advisor and target object. Then, we invoked methods.
The result was that only methods that contain the regular expressions in their name were intercepted by the pointcut.
The StaticMethodMatcherPointcut
abstract class is intended as a base for building static pointcuts.
The full qualified name of the class is:
org.springframework.aop.StaticMethodMatcherPointcut
We can use it as an anonymous inner class implementing the body of the method matches:
public static Pointcut exampleStaticPointcut = new StaticMethodMatcherPointcut() { public boolean matches(Method m, Class targetClass) { // implement custom check } };
Or extending it and implementing its methods:
public class StaticPointcutFooExample extends StaticMethodMatcherPointcut { public boolean matches(Method method, Class clazz) { return ("example".equals(method.getName())); } public ClassFilter getClassFilter() { return new ClassFilter() { public boolean matches(Class clazz) { return (clazz == MyTarget.class); } }; } }
This is an of example class to which apply advices:
package org.springaop.chapter.two.pointcut; public class PointcutTargetExample { public void printName(){ System.out.println("Max"); } public void printSpot(){ System.out.println("in Poetto beach"); } }
This is a second class of example to which apply advices:
package org.springaop.chapter.two.pointcut; public class PointcutTargetExampleTwo { public void printAction(){ System.out.println("swim"); } public void printSpot (){ System.out.println("on Mediterranean Sea"); } }
This is the StaticPointcutMatcher
method. It represents the class in which we set out the matching rules on the type of class and on the method.
package org.springaop.chapter.two.pointcut; import java.lang.reflect.Method; import org.springframework.aop.ClassFilter; import org.springframework.aop.support.StaticMethodMatcherPointcut; public class StaticPointcutMatcher extends StaticMethodMatcherPointcut { public boolean matches(Method method, Class cls) { return ("printSpot".equals(method.getName())); } public ClassFilter getClassFilter() { return new ClassFilter() { public boolean matches(Class cls) { return (cls == PointcutTargetExample.class); } }; } }
This is the advice. It represents the advice applied according to the StaticMethodMatcher
.
package org.springaop.chapter.two.pointcut; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class AdviceExample implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("Invoking " + invocation.getMethod().getName()); Object retVal = invocation.proceed(); System.out.println("Job Done"); return retVal; } }
This is the test class:
package org.springaop.chapter.two.pointcut; import org.aopalliance.aop.Advice; import org.springframework.aop.Advisor; import org.springframework.aop.Pointcut; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; public class StaticPointcutExample { public static void main(String[] args) { PointcutTargetExample one = new PointcutTargetExample(); PointcutTargetExampleTwo two = new PointcutTargetExampleTwo(); PointcutTargetExample proxyOne; PointcutTargetExampleTwo proxyTwo; Pointcut pc = new StaticPointcutMatcher(); Advice advice = new AdviceExample(); Advisor advisor = new DefaultPointcutAdvisor(pc, advice); ProxyFactory pf = new ProxyFactory(); pf.addAdvisor(advisor); pf.setTarget(one); proxyOne = (PointcutTargetExample)pf.getProxy(); pf = new ProxyFactory(); pf.addAdvisor(advisor); pf.setTarget(two); proxyTwo = (PointcutTargetExampleTwo)pf.getProxy(); proxyOne.printName(); proxyTwo.printAction(); proxyOne.printSpot(); proxyTwo.printSpot(); } }
The result will be:

Let's try to see what has been done. We defined two target classes, PointcutTargetExample
and PointcutTargetExampleTwo
(they print some text), and a StaticPointcutMatcher
, which is an around advice that prints, before the invocation, the name of the invoked method. Subsequently, the method invokes on the target class, and after the invocation it prints Job Done.
To test StaticPointcutMatcher
, we wrote the StaticPointcutExample
class with a main method.
Then we create an advisor that bound pointcut and advice, and created a new ProxyFactory
to which we set advisor and target objects. Then, we invoked methods.
The result was that only the methods of the class that satisfied StaticPointcutMatcher
were intercepted.
DynamicMethodMatcherPointcut
is intended as a base class to build dynamic pointcuts.
The full qualified name is:
org.springframework.aop.support .DynamicMethodMatcherPointcut
The utilization is not so different from that of StaticMethodMatcherPointcut
as the anonymous inner class:
public static Pointcut DynamicPointcutExample = new DynamicMethodMatcherPointcut() { public boolean matches(Method m, Class targetClass) { // implement custom check } public boolean matches(Method m, Class targetClass, Object[] args) { // implement custom check } }
As explained at the beginning of this chapter, the method matches with two arguments. It is called like staticMethodMatcher
, and if it returns true
, the matches are recalled at every invocation with three arguments.
Here is an example of its use:
This is the class to which advices are applied:
package org.springaop.chapter.two.pointcut; public class DynamicPointcutTargetExample { public void setSpot(String spot){ this.spot = spot; } public void printSpot(){ System.out.println(spot); } private String spot; }
As DynamicMethodMatcher
, we use a class that executes the static match (matches(Method method, Class cls)
) on the SetSpot
method, and the dynamic one (matches(Method method, Class cls, Object[] args)
) on parameters ending with "Ocean
".
package org.springaop.chapter.two.pointcut; import org.springframework.aop.ClassFilter; import org.springframework.aop.support.DynamicMethodMatcherPointcut; public class DynamicMethodMatcher extends DynamicMethodMatcherPointcut { public boolean matches(Method method, Class cls) { System.out.println("Static check for " + method.getName()); return ("setSpot".equals(method.getName())); } public boolean matches(Method method, Class cls, Object[] args) { System.out.println("Dynamic check for " + method.getName()); String spot = ((String) args[0]); return spot.endsWith("Ocean"); } public ClassFilter getClassFilter() { return new ClassFilter() { public boolean matches(Class cls) { return (cls == DynamicPointcutTargetExample.class); } }; } }
As advice we use the same class used in the StaticMethodMatcher's
example:
package org.springaop.chapter.two.pointcut; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class AdviceExample implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("Invoking " + invocation.getMethod().getName()); Object retVal = invocation.proceed(); System.out.println("Job Done"); return retVal; } }
This is the test class:
package org.springaop.chapter.two.pointcut; import org.springframework.aop.Advisor; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; public class DynamicPointcutExample { public static void main(String[] args) { DynamicPointcutTargetExample target = new DynamicPointcutTargetExample(); Advisor advisor = new DefaultPointcutAdvisor( new DynamicMethodMatcher(), new AdviceExample()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); DyinamicPointcutTargetExample proxy = ( DynamicPointcutTargetExample)pf.getProxy(); proxy.setSpot("Pacific Ocean"); proxy.setSpot("Mediterranean Sea"); proxy.setSpot("Atlantic Ocean"); proxy.printSpot(); proxy.printSpot(); proxy.printSpot(); } }
The result will be:

Let's see what has been done. We defined a target class (DynamicPointcutTargetExample
), a DynamicPointcutMatcher
with the definition of the class and of the method valid for the match, an around advice that prints the name of the invoked method before the invocation. Subsequently, the method is invoked on the target class, and after the invocation, it prints Job Done.
To test DynamicPointcutMatcher
, we wrote the DynamicPointcutExample
class with a main method.
Then we created an advisor that bound pointcuts and advices. We also created a new ProxyFactory
to which we set advisors and target objects. Then, we invoked methods.
The result was that at the first invocation, a static check was done on methods called from the proxy (the first four static checks). Then only when the static check was satisfied, the dynamic check was called to verify if we should apply advice.
- After Effects CC影視后期制作實戰(zhàn)從入門到精通
- 零基礎玩轉(zhuǎn)AI繪畫
- Procreate繪畫創(chuàng)作從入門到精通
- Microsoft SharePoint 2010 Administration Cookbook
- PPT 2016幻燈片設計與制作從入門到精通
- Django 1.2 E/commerce
- Photoshop網(wǎng)店美工實例教程(第2版 全彩微課版)
- Oracle 11g Streams Implementer's Guide
- 陌上花開:古風CG插畫繪制技法精解(花卉篇)
- AutoCAD 2016中文版基礎教程(全圖解視頻版)
- Power Query For Excel:讓工作化繁為簡
- 音樂制作7天速成:Cubase編曲教程
- Photoshop CC 2018基礎教程(第3版)
- Science Teaching with Moodle 2.0
- 計算機圖形制作CorelDRAW X6項目教程