Java Spring AOP:@annotation(annotation)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21588684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring AOP: @annotation(annotation)
提问by arcy
I am (of course) trying to maintain a project using many constructs I don't know that well. In the course of attempting to figure out the AOP use within Spring, I came across methods with the following annotation:
我(当然)试图使用许多我不太了解的结构来维护一个项目。在试图弄清楚 Spring 中 AOP 的使用过程中,我遇到了带有以下注释的方法:
@Around(value = "@annotation(annotation)")
@Around(value = "@annotation(annotation)")
So @Around means we're doing the 'around' version of the method pointcut in AOP, I understand that. I don't know what the other part means. The Spring documentation gives the following:
所以@Around 意味着我们正在AOP 中做方法切入点的'around' 版本,我理解这一点。我不知道另一部分是什么意思。Spring 文档给出了以下内容:
@annotation - limits matching to join points where the subject of the join point (method being executed in Spring AOP) has the given annotation
@annotation - 将匹配限制为连接点的主题(在 Spring AOP 中执行的方法)具有给定注释的连接点
I don't know what that means - "method being executed in Spring AOP" sounds like the advised method, but I don't know how I (or Spring) figure out which methods are being advised. It sounds like it is the methods that have "the given annotation", but if so, what annotation has been given?
我不知道这意味着什么——“在 Spring AOP 中执行的方法”听起来像是建议的方法,但我不知道我(或 Spring)如何确定建议的方法。听起来像是具有“给定注释”的方法,但如果是这样,则给出了什么注释?
What methods are advised by this annotation? And what else does it mean?
此注释建议使用哪些方法?还有什么意思?
采纳答案by Ori Dar
if you have the following Spring Bean:
如果您有以下 Spring Bean:
@Component
public class foo {
@com.pkg.Bar
void fooMe() {
}
}
Then the following Advice:
那么下面的忠告:
@Around("@annotation(com.pkg.Bar)")
Will invoke the interceptor around fooMe
(or any other Spring bean method annotated with @Bar
)
将调用周围的拦截器fooMe
(或任何其他带有注释的 Spring bean 方法@Bar
)
The @Transactional
annotation is a good example
该@Transactional
注释是一个很好的例子
回答by Sergej Ko??ejev
You would have a parameter named annotation
, of the appropriate type. It's called bound annotation, see this excerpt from the Spring AOP documentation:
您将有一个名为annotation
, 的适当类型的参数。它称为绑定注释,请参阅Spring AOP 文档中的摘录:
The following example shows how you could match the execution of methods annotated with an @Auditable annotation, and extract the audit code.
First the definition of the
@Auditable
annotation:@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Auditable { AuditCode value(); }And then the advice that matches the execution of
@Auditable
methods:@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)") public void audit(Auditable auditable) { AuditCode code = auditable.value(); // ... }
以下示例显示了如何匹配使用 @Auditable 注释注释的方法的执行,并提取审计代码。
首先是
@Auditable
注解的定义:@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Auditable { AuditCode value(); }然后是与
@Auditable
方法执行相匹配的建议:@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)") public void audit(Auditable auditable) { AuditCode code = auditable.value(); // ... }
回答by Deepak
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TimeLoggingAspect {
@Before("timeLoggingAspect()")
public void logBefore(JoinPoint joinPoint){
System.out.println("Method Name="+joinPoint.getSignature().getName());
System.out.println("Logging Before...");
}
/*
// Other way for AOP implemetation
@Pointcut("execution(public void userService())")
public void timeLoggingAspect(){
}
@After("timeLoggingAspect()")
public void logAfter() throws Exception{
System.out.println("Logging After...");
throw new Exception("Error after Logging");
}
@AfterThrowing(pointcut="timeLoggingAspect()",throwing="exception")
public void logAfterThrowingException(Exception exception){
System.out.println(exception.getLocalizedMessage());
}*/
}
/** Config class **/
import org.springframework.stereotype.Component;
import com.annotation.EnableMethodVisit;
@Component
@EnableMethodVisit
public class UserService {
public void userService(){
System.out.println("user service calling......");
}
}
/** Custom Annotation are used **/
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableMethodVisit {
}
/** UserService **/
import org.springframework.stereotype.Component;
import com.annotation.EnableMethodVisit;
@Component
@EnableMethodVisit
public class UserService {
public void userService(){
System.out.println("user service calling......");
}
}
/** AOP Test **/
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.aop.classes.UserService;
public class SpringAopTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AspectConfig.class);
ctx.refresh();
UserService userService = ctx.getBean(UserService.class);
userService.userService();;
}
}
回答by XianFaLiu
if you have the following Spring Bean:
如果您有以下 Spring Bean:
@Component
public class foo {
@com.pkg.Bar
void fooMe() {
}
}
and the following @interface:
以及以下@interface:
public @interface Bar {
String value() default "default value";
}
you can use the following Advice:
您可以使用以下建议:
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class BarAop {
@Around(value = "@annotation(bar)") // This 'bar' is one of the parameters of method around(point, bar)
public Object around(ProceedingJoinPoint point, Bar bar) throws Throwable {
String value = bar.value();
System.out.println(value); // will print "default value"
// execute target method
Object object = point.proceed();
System.out.println("return : " + object);
return object;
}
}
回答by G. Demecki
A small tip to complement existing, correct answers.
补充现有正确答案的小技巧。
To make @Aspect
annotation work, plain Spring requires @EnableAspectJAutoProxy
on the @Configuration
class. Or alternatively <aop:aspectj-autoproxy>
when XML is used. Spring Boot doesn't need it, because of its auto-configuration.
为了使@Aspect
注释起作用,类@EnableAspectJAutoProxy
上需要普通的 Spring @Configuration
。或者,<aop:aspectj-autoproxy>
当使用 XML 时。Spring Boot 不需要它,因为它是自动配置的。