我有一个 Spring Boot 2.7.6 应用程序。我有一些通过各种 Mongo 存储库管理的实体。我想用元数据扩展我的实体。因此,我想构建一个包含所有实体的元数据的元数据存储库,并使用包含默认实现的接口
IMetadata
来扩展实体。然后,此方法应使用方面从元数据存储库加载数据,然后返回它。
这就是我的课程的样子:
package io.zzzz.interfaces;
//imports are there
public interface IMetadata {
@JsonIgnore
default List<Metadata> getMetadata() {
return null;
}
package io.zzzz.entities;
//imports are there
@Getter
@Setter
@NoArgsConstructor
@Configurable
@Document("samples")
public class SampleEntity implements IMetadata {
@Id private String id;
// ... many other fields
package io.zzzz;
//imports are there
@Aspect
@Component
@EnableAspectJAutoProxy(proxyTargetClass=true)
@Slf4j
public class MetadataAspect implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
metadataService = context.getBean(MetadataService.class);
}
@Around("execution(* getMetadata(..))")
public Object getMetadataAdvice(ProceedingJoinPoint joinPoint) {
log.debug("Accessing metadata ...");
var metadataOwner = joinPoint.getTarget();
var md = metadataService.getMetadataForEntity((IMetadata) metadataOwner);
log.debug("Accessed metadata.");
return md;
}
}
我添加了以下依赖项:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>5.3.24</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.7</version>
</dependency>
我将
@EnableLoadTimeWeaving
添加到我的应用程序中,并且还在 VM 选项中添加了 javaagent -javaagent:<path>/spring-instrument-5.3.24.jar
。
因为这些都不起作用,所以我在
aop.xml
中创建了以下META-INF
:
<aspectj>
<weaver>
<include within="io.zzzz.entities..*"/>
</weaver>
<aspects>
<aspect name="io.zzzz.MetadataAspect"/>
</aspects>
</aspectj>
我添加了 VM 选项
-Daj.weaving.verbose=true
以在启动期间扩展日志记录以查看是否发生了某些情况。我看到了一些编织,所以至少应该可以工作。如果我更一般地制定切面和 aop-config ,那么我也会看到,例如,服务方法被调用并通过切面传递,但我的 getMetadata
方法不是。
我不知道该怎么办。也许我的想法根本行不通。
我希望
能够由SampleEntity
注解由 spring 管理
@Configurable
不,它仍然是非托管的,没有任何
@Component
、@Service
或类似的 Spring 组件注释。顾名思义,它只是使非托管对象可配置,即您可以使用@Autowired
将Spring bean注入其中。请参阅 这个 Baeldung 教程,当然还有 Spring 文档以获取更多信息:
请注意,您需要结合
spring-aspects
方面库激活原生Aspect编织,才能使@Configurable
通过AnnotationBeanConfigurerAspect
产生任何效果。
更新:我忘了提一下,如果你想将 AOP 应用于非托管类,你可以选择让它们像前面提到的那样进行托管,或者使用本机 AspectJ,它没有这种与 Spring 相关的限制,并且可以应用于 POJO 代码,无论有没有 Spring。 AspectJ 也不需要或创建任何代理。