spring-framework
spring-framework copied to clipboard
Add reverse methed in MethodMatchers and ClassFilters
Add reverse methed in MethodMatchers and ClassFilters.
Add support for MethodMatchers and ClassFilters to reverse the given MethodMatcher and ClassFilter. It is convenient in some complex conditions,Or is there another way to do it?Thanks.
@cuspymd Thanks for the reply. Some complex combinations are handy, for example in the SpringCloud, if I need to develop a spring-boot-starter project that collects logs for all requests by default and provides @logIgnore to ignore certain requests. For Feign, I could write the Advisor like this:
public class Example {
/**
* this FeignClient require logging
*/
@FeignClient("svr-name")
public interface Client extends Api {
}
/**
* this FeignClient does not require logging
*/
@LogIgnore
@FeignClient("svr-name")
public interface IgnoreClient extends Api {
}
/**
* in other Jar
*/
interface Api {
/**
* this method does not require logging
*/
@LogIgnore
@RequestMapping("/ignoreApi")
void ignoreApi();
/**
* this method require logging
*/
@RequestMapping("/api")
void api();
}
/**
* Annotated classes or methods do not need to be logged
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@interface LogIgnore {
}
/**
* The Advisor for Feign
*/
public class FeignAdvisor extends AbstractPointcutAdvisor {
@Override
public Pointcut getPointcut() {
return new Pointcut() {
@Override
public ClassFilter getClassFilter() {
//This class mast contain @FeignClient
ClassFilter cf1 = new AnnotationClassFilter(FeignClient.class, true);
//This class cannot contain @LogIgnore
ClassFilter cf2 = ClassFilters.reversion(new AnnotationClassFilter(LogIgnore.class, true));
//maybe more ClassFilter
return ClassFilters.intersection(cf1, cf2);
}
@Override
public MethodMatcher getMethodMatcher() {
//This method mast contain @RequestMapping
MethodMatcher cf1 = new AnnotationMethodMatcher(RequestMapping.class, true);
//This method cannot contain @LogIgnore
MethodMatcher cf2 = MethodMatchers.reversion(new AnnotationMethodMatcher(LogIgnore.class, true));
//maybe more MethodMatcher
return MethodMatchers.intersection(cf1, cf2);
}
};
}
@Override
public Advice getAdvice() {
//do something
return (MethodInterceptor) (MethodInvocation invocation) -> invocation.proceed();
}
}
}
Some complex combinations are handy, for example in the SpringCloud, if I need to develop a spring-boot-starter project that collects logs for all requests by default and provides @logIgnore to ignore certain requests. For Feign, I could write the Advisor like this:
Thanks for the detailed explanation. It looks very useful.
@rstoyanchev Could you please have a look into this?
Hi, I am a beginner with Open source contributions. This would be my first contribution, can anyone please guide me through it?
@Pulkit-Garg15 thanks for the offer but this is already a PR (see the "Files Changed" tab above) so this isn't open for contribution.
I think a negate
on ClassFilter
can be added as it is a functional interface. I am wondering if we should do the same for MethodFilter
though, and how important the equals/hashCode bit is.
I think a
negate
onClassFilter
can be added as it is a functional interface.
I agree. It's analogous to java.util.function.Predicate.negate()
in that sense.
Along the same lines, I could see it being useful to have something like the static java.util.function.Predicate.not(Predicate<? super T>)
companion method.
I am wondering if we should do the same for
MethodFilter
though,
I imagine that could be handy in MethodMatcher
, too.
and how important the equals/hashCode bit is.
The filters are used to differentiate pointcuts -- for example, in org.springframework.aop.support.ComposablePointcut.equals(Object)
. So, unless I'm mistaken, proper equals
and hashCode
implementations will be required (for example, #15899).
Such a shame that we can't do the negate
idea as a default method. We have several components in the framework that implements both interface so we're kinda stuck there :/
@Jinhui-Z thanks very much for making your first contribution to Spring Framework.
This seems to have been shipped with 6.1.0-M5 but doesn't have a milestone. There's also a typo in "metheds" in the title.
Good catch @izeye. I've fixed the title and added the missing entry manually to the release notes.