我对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;
}
}
我为名称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-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'
感谢您的帮助
使用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
中找到此用法的示例