问题
Is there a Spring AOP annotation which lets us go inside a method only if that annotation returns true?
I want something like this:
@CustomAnnotation
public String foo(){
System.out.println("Hello World");
return "foo";
}
So now only when the @CustomAnnotation returns true is when we will go inside the foo() method & print Hello World & return the String "foo" , but when @CustomAnnotation return false - we won't go inside the foo() method at all.
回答1:
To use AOP with spring you should add to pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.12</version>
<scope>compile</scope>
</dependency>
or only one dependency for spring boot projects
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
To create custom annotation we need SkipOnCondition.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SkipOnCondition {
}
We need to configure our aspect EchoAspect.java. To be able to skip method we selected Around
interception point. The trigger for the interception will be specified annotation. ProceedingJoinPoint can provide all details about intercepted method. For example: arguments, signeture, ...
@Aspect
@Configuration
public class EchoAspect {
private Logger logger = LoggerFactory.getLogger(EchoAspect.class);
@Around("@annotation(com.example.demo.aop.SkipOnCondition)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
if ("skip".equals((String) joinPoint.getArgs()[0])){
logger.info("Condition is true the method will be skipped.");
return null;
}
return joinPoint.proceed();
}
}
An object under test Echo.java has void and method with return type.
@Component
public class Echo {
private Logger logger = LoggerFactory.getLogger(Echo.class);
@SkipOnCondition
public String echo (String s) {
return s;
}
@SkipOnCondition
public void blindEcho (String s) {
logger.info(s);
}
}
And proof of concept EchoTest.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class EchoTest {
private Logger logger = LoggerFactory.getLogger(EchoTest.class);
@Autowired
private Echo echo;
@Test
public void testEcho() {
echo.blindEcho("boom");
echo.blindEcho("skip");
logger.info(echo.echo("boom"));
logger.info(echo.echo("skip"));
}
}
The output will show us how it works. echo.blindEcho("boom");
doesn't satisfy the condition and will be executed as expected. echo.blindEcho("skip");
will be intercepted as result special logging message will only appear. logger.info(echo.echo("boom"));```` doesn't satisfy the condition and will be executed as expected.
logger.info(echo.echo("skip"));``` will be intercepted as result special logging message will appear and because the method has a return type the logger will print null.
com.example.demo.aop.Echo : boom
com.example.demo.aop.EchoAspect : Condition is true the method will be skipped.
com.example.demo.aop.EchoTest : boom
com.example.demo.aop.EchoAspect : Condition is true the method will be skipped.
com.example.demo.aop.EchoTest : null
Good example with more details, link
来源:https://stackoverflow.com/questions/53791423/is-there-a-spring-aop-annotation-which-lets-us-go-inside-a-method-only-if-that-a