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
找到它的示例用法
我是 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
找到它的示例用法