How to match two patterns in one pointcut expression - spring

I want to define my pointcut to match two kinds of methods:
all methods from class org.mypackage.Foo with names starting with "update"
all methods from the same class with names starting with "delete"
I tried the following:
#Before("execution (* org.mypackage.Foo.update*(..) ) && execution(* org.mypackage.Foo.delete*(..) )")
public void verify()
{
//verify if user has permission to modify...
}
It doesn't work. When I call either a Foo.update*() method or a Foo.delete*() method, verify() is not invoked.
How should I change it?

There are 2 option to match patterns in pointcut expression. The pointcut expression may be either a simple reference to a named pointcut, or a pointcut expression declared in place.
By creating individual method for respective point cut. And using that method name as reference in #Before advice.
#Pointcut("execution(* org.mypackage.Foo.update*(..))")
private void fooUpdate() {}
#Pointcut("execution(* org.mypackage.Foo.delete*(..))")
private void fooDelete() {}
#Before("fooUpdate() || fooDelete()")
public void verify() {
// verify if user has permission to modify...
}
Directly declaring pointcut expression in place.
#Before("execution(* org.mypackage.Foo.update*(..)) || execution(* org.mypackage.Foo.delete*(..))")
public void verify() {
// verify if user has permission to modify...
}

Change && to || in your expression.

Related

Check annotation value in Spring Pointcut Expression

I'm trying to add an aspect that is only applied on 'non- readonly transactions', so not for #Transactional(readonly=true)
This below code is applied for all methods that have an #Transactional annotation above it.
#AfterReturning("#annotation(org.springframework.transaction.annotation.Transactional)")
public void afterTransaction() {...}
There is an alternative by getting the information from the JoinPoint but it is cumbersome and I'd rather not go down that path.
The documentation seems not very specific about this.
You can use an execution pointcut in order to limit annotation matching to joinpoints where the annotation has certain parameter values.
Simple annotation value matching
#AfterReturning("execution(#org.springframework.transaction.annotation.Transactional(readOnly=true) * *(..))")
public void process(JoinPoint joinPoint) {
System.out.println(joinPoint);
}
Annotation value matching + annotation parameter binding
#AfterReturning("execution(#org.springframework.transaction.annotation.Transactional(readOnly=true) * *(..)) && #annotation(transactional)")
public void process(JoinPoint joinPoint, Transactional transactional) {
System.out.println(joinPoint + " -> " + transactional);
}

Spring AOP: differences between && and 'and'

I have this interface:
public interface Performance {
public void perform();
}
Implemented by this class:
#Component
public class PerformanceImplementation implements Performance {
public void perform() {
System.out.println("PerformanceImplementation.perform()");
}
}
I want to apply the following aspect to the method of the interface above but only if the method is executed within another package, so I use the within designator using that package name
#Aspect
public class Audience {
#Pointcut("execution(** concert.Performance.perform(..)) " +
"and within(asdasdasd.*)")
public void performance() {}
#Around("performance()")
public void watchPerformance(ProceedingJoinPoint jp) {
try {
System.out.println("Silencing cell phones");
System.out.println("Taking seats");
jp.proceed();
System.out.println("CLAP CLAP CLAP!!!");
} catch (Throwable e) {
System.out.println("Demanding a refund");
} }
}
If I use and instead of && the aspect will be triggered anyway and it seems that it is not considering the limitation of the designator.
Is there any reason why this happens?
It depends whether you are using them inside annotation or xml .
Pointcut expressions can be combined using '&&', '||' and '!'
#Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {}
When combining pointcut sub-expressions, '&&' is awkward within an XML document, and so the keywords 'and', 'or' and 'not' can be used in place of '&&', '||' and '!' respectively. For example, the previous pointcut may be better written as:
<aop:pointcut id="businessService"
expression="execution(* com.xyz.myapp.service.*.*(..)) **and** this(service)"/>

Dynamic pointcut expression in aspectj/spring aop

I want to create a pointcut expression which is dynamic in nature.
I have three packages -
package1,
package2,
common
common should always be inculded and based on system property i want to load package1 OR package2 at any given time
Something like below
private static final String PACKAGE = System.getProperty("packagePrefix");
#Around("execution(* "+PACKAGE+"..*.*(..)) && execution(* ..common.*(..))")
how can i achieve this?
EDIT:
I have found this which is quite interesting and i guess will solve my requirement but not able to get it working
So this link says to have like below
#Aspect
public abstract class MyAspect {
protected abstract pointcut();
#Before("pointcut()")
public void myAdviceMethod() {
// Advice code goes here
}
}
public class ConcreteAspect extends MyAspect {
#Pointcut("execution(* com.acme.*.*(..))")
protected pointcut() {
)
}
Included below in my Java config
#Bean
public ConcreteAspect myAspect() {
return new ConcreteAspect();
}
But getting below error :
java.lang.IllegalArgumentException: error at ::0 can't find referenced
pointcut pointcut
I guess at run time its not able to find out overriden pointcut method and hence not able to resolve pointcut.
Any idea how can I fix this?
You could use an if() clause to make a check like this:
aspect X {
before(): execution(* Code.*(..)) &&
if(isOfInterest(thisJoinPointStaticPart.getSignature().getDeclaringType())) {
System.out.println("advice running");
}
public static boolean isOfInterest(Class s) {
return s.getPackage().toString().startsWith(packagePrefix);
}
}
I think something similar will work for annotation style syntax. But this approach will include a runtime test at every matched join point.
You can use within, which will scan the given packages
#Pointcut("within(..common..(..)")
public void CommonPackage(){}
#Pointcut("within(..PACKAGE..(..)")
public void specificPackage(){}
And using #Around/#Before or any advice as u require for your situation
#Around("execution(CommonPackage()&&SpecificPackage()")
Writing the pointcut expression for the different packages and binding them together. Hope this helps!

AspectJ pointcut expression for all classes that contains a especific word in their names

What's up? folks!
I'm trying to intercept all classes that contains a specific word in their names... something as below:
#Before("execution(* com.domain.model.*.*Repository.save(..))")
I have the following methods to intercept:
com.domain.model.user.UserRepository.save(User user);
com.domain.model.xpto.XPTORepository.save(XPTO xpto);
com.domain.model.foo.FooRepository.save(Foo foo);
I have tried this: (worked, but looks horrible)
#Before("execution(* *.save(..)) && within(com.domain.model..*)")
public void validateBeforeSave(final JoinPoint jp) throws Throwable {
if (jp.getSignature().toString().contains("Repository.")) {
...
}
}
Thanks!!!
What is the problem with your own suggestion?
execution(* com.domain.model.*.*Repository.save(..))
should work nicely with the sample package + class names you provided. If is does not work your real package names are different, e.g. you have more than one subpackage below model. In this case you can make the pointcut more generic using the .. construct which is also used in your ugly workaround:
execution(* com.domain.model..*Repository.save(..))
Or maybe your *Repository classes all inherit from a common superclass or implement the same interface, e.g. interface com.domain.model.Repository or abstract class com.domain.model.BaseRepository. In this case you could do without the string matching and just use something like
execution(* com.domain.model.Repository+.save(..))
or
execution(* com.domain.model.BaseRepository+.save(..))
The + means "this class and all of its subclasses".

can we have mutiple pointcuts mapped to a single advice

In aspectj , can we have multiple pointcuts mapped to the single advice ?
for example below are two separate pointcuts
#Pointcut("execution(* xyz.get(..))")
void pointcut1() {
}
#Pointcut("execution(* abc.put(..))")
void pointcut2() {
}
so can anyone give idea how to configure these two pointcuts on a single advice ?
because for single pointcut to single advice like below we have
#Before("pointcut1()")
public void beforeLogging() {
System.out.println("Before Methods");
}
how to configure the same advice for multiple pointcuts ?
Yes, you can combine pointcuts with logical AND (&&) as well as logical OR(||) operators or negate them by logical NOT (!).
What you probably want here is this:
#Before("pointcut1() || pointcut2()")
The OR makes sense here because in your example a logical AND would always lead to an empty set: a method cannot be in two packages at the same time, but in one of them alternatively.
You can use the || operator.
From the docs http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/aop.html (9.2.2 Declaring an aspect):
#Pointcut("execution(public * (..))")
private void anyPublicOperation() {}
#Pointcut("within(com.xyz.someapp.trading..)")
private void inTrading() {}
#Pointcut("anyPublicOperation() || inTrading()")
private void tradingOperation() {}

Resources