- 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.
- Alfresco Developer Guide
- JasperReports for Java Developers
- 突破平面Premiere Pro 2022短視頻與視頻制作
- Excel 2013電子表格處理
- 中文版Photoshop 2020基礎教程
- Excel 2016入門與提高
- After Effects影視動畫特效及欄目包裝案例實戰
- Building Websites with VB.NET and DotNetNuke 4
- AutoCAD 2016中文版基礎教程(全圖解視頻版)
- AutoCAD 2022中文版從入門到精通(標準版)
- IBM Lotus Notes and Domino 8.5.1
- 中文版Photoshop平面設計入門教程
- 中文版3ds Max 2020基礎教程
- Troux Enterprise Architecture Solutions
- AutoCAD 2018中文版完全自學手冊