简体   繁体   English

Spring AOP:@annotation(annotation)

[英]Spring AOP: @annotation(annotation)

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.所以@Around 意味着我们正在AOP 中做方法切入点的'around' 版本,我理解这一点。 I don't know what the other part means.我不知道另一部分是什么意思。 The Spring documentation gives the following: 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.我不知道这意味着什么——“在 Spring AOP 中执行的方法”听起来像是建议的方法,但我不知道我(或 Spring)如何确定建议的方法。 It sounds like it is the methods that have "the given annotation", but if so, what annotation has been given?听起来像是具有“给定注释”的方法,但如果是这样,则给出了什么注释?

What methods are advised by this annotation?此注释建议使用哪些方法? And what else does it mean?还有什么意思?

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调用拦截器(或任何其他用@Bar注释的 Spring bean 方法)

The @Transactional annotation is a good example @Transactional注释就是一个很好的例子

You would have a parameter named annotation , of the appropriate type.您将有一个名为annotation的参数,该参数具有适当的类型。 It's called bound annotation, see this excerpt from the Spring AOP documentation :它称为绑定注释,请参阅Spring AOP 文档中的摘录:

The following example shows how you could match the execution of methods annotated with an @Auditable annotation, and extract the audit code.以下示例显示了如何匹配使用 @Auditable 注释注释的方法的执行,并提取审计代码。

First the definition of the @Auditable annotation:首先是@Auditable注解的定义:

\n@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)\n@Target(ElementType.METHOD) @目标(元素类型。方法)\npublic @interface Auditable {公共@interface 可审计{\n    AuditCode value();审计代码值();\n} }\n

And then the advice that matches the execution of @Auditable methods:然后是与@Auditable方法的执行相匹配的建议:

\n@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)") @Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")\npublic void audit(Auditable auditable) {公共无效审计(Auditable auditable){\n    AuditCode code = auditable.value();审计代码代码 = auditable.value();\n    // ... // ...\n} }\n

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;
    }
}

A small tip to complement existing, correct answers.小提示来补充现有的,正确的答案。

To make @Aspect annotation work, plain Spring requires @EnableAspectJAutoProxy on the @Configuration class.为了使@Aspect注解工作,素春要求@EnableAspectJAutoProxy@Configuration类。 Or alternatively <aop:aspectj-autoproxy> when XML is used.或可替代地<aop:aspectj-autoproxy>使用XML时。 Spring Boot doesn't need it, because of its auto-configuration.春季启动并不需要它,因为它的自动配置。

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();;
    }
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM