Spring Boot 中实体的面向方面扩展

问题描述 投票:0回答:1

我有一个 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
方法不是。

我不知道该怎么办。也许我的想法根本行不通。

spring-boot aspectj spring-data-mongodb spring-aop load-time-weaving
1个回答
0
投票

我希望

SampleEntity
能够由
@Configurable
注解由 spring 管理

不,它仍然是非托管的,没有任何

@Component
@Service
或类似的 Spring 组件注释。顾名思义,它只是使非托管对象可配置,即您可以使用
@Autowired
将Spring bean注入其中。请参阅 这个 Baeldung 教程,当然还有 Spring 文档以获取更多信息:

请注意,您需要结合

spring-aspects
方面库激活原生Aspect编织,才能使
@Configurable
通过
AnnotationBeanConfigurerAspect
产生任何效果。


更新:我忘了提一下,如果你想将 AOP 应用于非托管类,你可以选择让它们像前面提到的那样进行托管,或者使用本机 AspectJ,它没有这种与 Spring 相关的限制,并且可以应用于 POJO 代码,无论有没有 Spring。 AspectJ 也不需要或创建任何代理。

© www.soinside.com 2019 - 2024. All rights reserved.