Spring AOP - 在 POJO 上设置通知 getter - 不调用通知

Spring AOP - Setting Advice on a POJO getter - advice is not called

我是 Spring 的新手,我想使用 Spring AOP 在调用 POJO getter 时触发建议。

我创建了一个简单的 POJO:

package com.atlas.datastore.datadomain;

import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.stereotype.Component;

@Component
public class Person
{
   private String name;

   public String getName() {
       System.out.println(name);
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }
}

然后我为名称 getter 创建了一个方面:

package com.atlas.datastore.aspects;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class personAspect {
    @Pointcut("execution(* com.atlas.datastore.datadomain.Person.getName())")
    private void getName() {}

    @Before("getName()")
    public void doBeforeTask(){
       System.out.println("My name is: " );
    }
}

我创建了一个控制器(spring 引导简单应用程序)来使用 getter:

package com.example.Controller;

import com.atlas.datastore.datadomain.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/person")
public class PersonController {

   @Autowired
   private Person person;

   @RequestMapping(value = "/{personId}", method = RequestMethod.GET)
   @ResponseBody()
   public Person personAction(@PathVariable String personId) {

       person.setName("John");

       person.getName();

       return person;
   }
}

当我 运行 应用程序一切正常时,我可以看到正在触发建议。

我的问题是我不想 auto-wire Person 对象。当我使用默认构造函数(使用 new 关键字)创建一个 Person 时,我看到 advice 没有被触发:

package com.example.Controller;

import com.atlas.datastore.datadomain.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/person")
public class PersonController {

   @RequestMapping(value = "/{personId}", method = RequestMethod.GET)
   @ResponseBody()
   public Person personAction(@PathVariable String personId) {

       Person person = new Person();

       person.setName("John");

       person.getName();

       return person;
   }
}

在我的配置中,我使用了以下注释:

@EnableAspectJAutoProxy(proxyTargetClass = true)

我可以在日志中看到以下输出:

18:12:40.152 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'person'
18:12:40.152 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'person'
18:12:40.152 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'person' to allow for resolving potential circular references
18:12:40.153 [main] DEBUG o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Creating implicit proxy for bean 'person' with 0 common interceptors and 2 specific interceptors
18:12:40.153 [main] DEBUG o.s.aop.framework.CglibAopProxy - Creating CGLIB proxy: target source is SingletonTargetSource for target object [com.atlas.datastore.datadomain.Person@7de4a01f]
18:12:40.154 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'person'

非常感谢你的帮助

而不是将@Pointcut 添加到域对象: com.atlas.datastore.datadomain.Person.getName()

考虑创建一个以 Person 对象作为参数的服务。将 @Pointcut 添加到服务方法。 将服务注入您的 Web 控制器,然后调用传递 'new' 人的服务。

使用 new 运算符直接创建实例,如 Person person = new Person() 绕过 Spring,因此 Spring 没有机会在此对象中注入依赖项或代理此对象对象。

要使Spring为上述使用new运算符的场景注入依赖或代理,我们需要将Person对象注释为@Configurable,配置AnnotationBeanConfigurerAspect,使用 Spring LoadTimeWeaving 和 运行 具有 -javaagent .....

的应用程序

您可以在 https://dzone.com/articles/domain-object-dependency-injection-with-spring

找到它的示例用法