- Spring 2.5 Aspect Oriented Programming
- Massimiliano Dessi
- 1062字
- 2021-05-21 20:23:13
Operations on Pointcut
The Pointcut
class exposes two methods for the union and intersection of pointcuts.
public static Pointcut union (Pointcut a, Pointcut b) public static Pointcut intersection (Pointcut a, Pointcut b)
The union of two pointcuts is the pointcut matching any method matched by either pointcut (Boolean OR). The intersection matches only methods matched by both pointcuts (Boolean AND).
Pointcuts can be composed using the static methods in the org.springframework.aop.support.Pointcuts
(union and intersection) class, or using the ComposablePointcut
class in the same package.
The ComposablePointcut
class is used to compose two or more pointcuts together with operations such as union()
and intersection()
.
The full qualified name of the class is:
org.springframework.aop.support.ComposablePointcut
By default, ComposablePointcut
is created with a ClassFilter
that matches all the classes and a MethodMatcher
that matches all the methods.
We can supply our own initial ClassFilter
and MethodMatcher
if we like:
ComposablePointcut(ClassFilter classFilter, MethodMatcher methodMatcher)
The union()
and intersection()
methods are both overloaded to accept ClassFilter
and MethodMatcher
arguments.
Invoking the union()
method, the MethodMatcher
of ComposablePointcut
is replaced with a UnionMethodMatcher
that uses the current MethodMatcher
of the ComposablePointcut
and the MethodMatcher
passed to the union()
method as arguments.
The UnionMethodMatcher
method then returns true
for a match if either of its wrapped MethodMatchers
returns true
.
This way it is possible to invoke the union()
method as many times as we want, with each call creating a new UnionMethodMatcher
that wraps the current MethodMatcher
with the MethodMatcher
passed to union()
.
Internally, the intersection()
method works in a similar way to the union ()
.
Here is the target class:
package org.springaop.chapter.two.pointcut; import java.util.Date; public class ComposableTargetExample { public ComposableTargetExample() { startDate = new Date(); } public ComposableTargetExample(String description) { startDate = new Date(); this.description = description; } public void setDescription(String description) { this.description = description; } public String getDescription() { return description; } public Date getStartDate() { return (Date) startDate.clone(); } private Date startDate; private String description; }
Here is the example class:
package org.springaop.chapter.two.pointcut; import java.lang.reflect.Method; import org.springframework.aop.Advisor; import org.springframework.aop.ClassFilter; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.ComposablePointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.StaticMethodMatcher; public class ComposablePointcutExample { public static void main(String[] args) { ComposableTargetExample target = new ComposableTargetExample(); ComposablePointcut pc = new ComposablePointcut( ClassFilter.TRUE, new GetterMethodMatcher()); System.out.println("Test GetterMetodMatcher :"); ComposableTargetExample proxy = getProxy(pc, target); testInvoke(proxy); System.out.println("Test GetterMetodMatcher UNION SetterMethodMatcher :"); pc.union(new SetterMethodMatcher()); proxy = getProxy(pc, target); testInvoke(proxy); System.out.println("Test (GetterMetodMatcher UNION SetterMethodMatcher) INTERSECT GetStartDateMethodMatcher :"); pc.intersection(new GetStartDateMethodMatcher()); proxy = getProxy(pc, target); testInvoke(proxy); } private static ComposableTargetExample getProxy( ComposablePointcut pc, ComposableTargetExample target) { Advisor advisor = new DefaultPointcutAdvisor(pc, new ComposableBeforeAdvice()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); return (ComposableTargetExample) pf.getProxy(); } private static void testInvoke(ComposableTargetExample proxy) { proxy.getStartDate(); proxy.getDescription(); proxy.setDescription("New Description"); } private static class GetterMethodMatcher extends StaticMethodMatcher { public boolean matches(Method method, Class cls) { return (method.getName().startsWith("get")); } } private static class GetStartDateMethodMatcher extends StaticMethodMatcher { public boolean matches(Method method, Class cls) { return "getStartDate".equals(method.getName()); } } private static class SetterMethodMatcher extends StaticMethodMatcher { public boolean matches(Method method, Class cls) { return (method.getName().startsWith("set")); } } }
The result will be:

Let's try to see what has been done. We defined a target class (ComposableTargetExample
), a ComposableBeforeAdvice
that prints "ComposableBeforeAdvice
".
To test ComposablePointcut
we wrote the ComposableTargetExample
class with a main method.
In a getProxy
method, we created an advisor that bound pointcuts and advices, created a new ProxyFactory
to which we set advisors and target objects, and returned the target object.
In the testInvoke
method, we invoked two Get
methods and one Set
method.
In the Main
method, we created the pointcut declaring we wanted to use a GetterMethodMatcher
, and we called testInvoke
. The result was the application of the advice to two Get
methods. Then we made a union of pointcuts that at the beginning contained the GetterMethodMatcher
with a SetterMethodMatcher
, and then we called the testInvoke
method. The result was the application of the advice three times.
Then we make the intersection with a GetStartDateMethodMatcher
, and call the testInvoke
method. The result is the application of advice only on the method that satisfies the intersection.
The ControlFlowPointcut
is a pointcut that matches all methods within the control flow of another method—that is, any method that is invoked either directly or indirectly as the result of another method being invoked.
Control flow pointcuts allow us to apply advices to an object in a selective manner depending on the context in which it is executed.
The full qualified name of the class is:
org.springframework.aop.support.ControlFlowPointcut
However, we have to pay attention to the performance we get when using it. The Spring documentation indicates that a control flow pointcut is typically five times slower than other pointcuts on a 1.4 JVM, and ten times slower on a 1.3 JVM.
Here is the target class:
package org.springaop.chapter.two.pointcut; public class ControlFlowTargetExample { public void greeting(){ System.out.println("Cheers"); } }
This is the before advice:
package org.springaop.chapter.two.pointcut; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class ControlFlowBeforeAdvice implements MethodBeforeAdvice { public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("ControlFlow beforeAdvice "); } }
Here is the example class:
package org.springaop.chapter.two.pointcut; import org.springframework.aop.Advisor; import org.springframework.aop.Pointcut; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.ControlFlowPointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; public class ControlFlowPointcutExample { public static void main(String[] args) { ControlFlowPointcutExample ex = new ControlFlowPointcutExample(); ex.run(); } public void run() { ControlFlowTargetExample target = new ControlFlowTargetExample(); Pointcut pc = new ControlFlowPointcut(ControlFlowPointcutExample.class, "test"); Advisor advisor = new DefaultPointcutAdvisor(pc, new ControlFlowBeforeAdvice()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); ControlFlowTargetExample proxy = (ControlFlowTargetExample) pf.getProxy(); System.out.println("Trying normal invoke"); proxy.greeting(); System.out.println("Trying under ControlFlowPointcutExample.test()"); test(proxy); } private void test(ControlFlowTargetExample bean) { bean.greeting(); } }
The result will be:

Let's see what has been done. We defined a target class (ControlFlowTargetExample
), a ControlFlowBeforeAdvice
that prints ControlFlow beforeAdvice.
To test ControlFlowPointcut
, we wrote the ControlFlowPointcutExample
class with a main method that only calls a run method, where we put the real test body. We did this to show the effects of the flow of a calling of a method from a given class.
The result was that when the method was called directly by the proxy, the advice was not applied, whereas when the call came from within another object (ControlFlowPointcutExample
in this case), the advice was applied.
For the common operations, pointcut constants are available in this package:
org.springframework.aop.support.Pointcuts
The constants are:
GETTERS
is a constant Pointcut object, matching all bean property getters, in any class.
SETTERS
is a constant Pointcut object matching all bean property setter in any class.
- 中文版AutoCAD 2015實用教程
- 數(shù)據(jù)、模型與決策:基于Excel的建模和商務應用
- Photoshop CC 2018實用教程
- AutoCAD 2014中文版完全自學手冊
- 計算機·手機生活應用
- 詳解AutoCAD 2022機械設計(第6版)
- 中文版Illustrator CC實戰(zhàn)視頻教程
- 綁定的藝術:Maya高級角色骨骼綁定技法(第2版)
- 深入理解OpenCV:實用計算機視覺項目解析(原書第3版)
- Learning the Yahoo! User Interface library
- 新編 中文版Photoshop平面設計入門與提高
- Microsoft SharePoint 2010 and Windows PowerShell 2.0: Expert Cookbook
- Microsoft Windows Communication Foundation 4.0 Cookbook for Developing SOA Applications
- After Effects 影視后期特效:短視頻制作實戰(zhàn)寶典
- Alfresco 3 Cookbook