Spring AOP-关于POJO getter的设置建议-建议不被调用建议、不被、AOP、Spring

2023-09-03 11:46:38 作者:微心雨恋

我对Spring还很陌生,我想使用Spring AOP在调用POJO获取方法时发出通知。

我创建了一个简单的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;
   }
}
AOP

我为名称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 Boot简单应用程序)来使用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-wirePerson对象。当我使用默认构造函数(使用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'

感谢您的帮助

推荐答案

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

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

运行应用程序

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

中找到此用法的示例