单独模块中使用的 Spring AOP 方面 [英] Spring AOP aspect used in a separate module

查看:39
本文介绍了单独模块中使用的 Spring AOP 方面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个 maven 项目模块中有一个方面 com.x.NiceAspect,在一个单独的 maven 模块中有一个类 com.x.NiceClass.这些模块具有相同的 POM 父级,共同创建一个项目.

我想要实现的目标是拥有一个通用方面,我可以将其包含在该项目的所有 Maven 模块中.

现在 NiceAspect 中的切入点是 execution(* com.x...set(..)) 表示我的包中的所有 setter 方法.>

我希望这方面与第二个模块一起运行,尤其是加入 NiceClass

我怎样才能做到这一点?

此外,假设 Aspect 需要在第二个模块中定义的类的参数,那么我最终会得到循环依赖..

感谢任何帮助

亲切的问候,

x.

解决方案

  • 我希望这方面与第二个模块一起运行,尤其是加入 NiceClass

    如果切入点与另一个"模块中的方法匹配,则该方面将适用.除了正确设置依赖项之外,您不需要做任何特别的事情.例如,全局导入您的 AOP 配置.

  • 此外,假设 Aspect 需要在第二个模块中定义的类的参数,那么我最终会得到循环依赖..

    对类参数的方面依赖不应该导致循环依赖,因为您有一个连接两者的父 POM,并且在运行时两个模块都在一个类路径中.

一般情况下,建议遵循Spring描述的Aspect结构documentation => 创建一个整体的 SystemArchitecture 方面,然后根据需要添加更多范围缩小的方面:

@Aspect公共类系统架构{/*** 如果定义了方法,则连接点位于 web 层中* 在 com.xyz.someapp.web 包或任何子包中的类型* 在那个之下.*/@Pointcut("within(com.xyz.someapp.web..*)")public void inWebLayer() {}/*** 如果定义了方法,则连接点位于服务层* 在 com.xyz.someapp.service 包或任何子包中的类型* 在那个之下.*/@Pointcut("within(com.xyz.someapp.service..*)")public void inServiceLayer() {}/*** 如果定义了方法,则连接点位于数据访问层中* 在 com.xyz.someapp.dao 包或任何子包中的类型* 在那个之下.*/@Pointcut("within(com.xyz.someapp.dao..*)")public void inDataAccessLayer() {}/*** 业务服务是对服务定义的任何方法的执行* 界面.这个定义假设接口被放置在* 服务"包,实现类型在子包中.** 如果您按功能区域对服务接口进行分组(例如,* 在包 com.xyz.someapp.abc.service 和 com.xyz.def.service 中)然后* 切入点表达式execution(* com.xyz.someapp..service.*.*(..))"* 可以代替.** 或者,您可以使用bean"编写表达式* PCD,就像bean(*Service)"一样.(这假设你有* 以一致的方式命名您的 Spring 服务 bean.)*/@Pointcut("执行(* com.xyz.someapp.service.*.*(..))")public void businessService() {}/*** 数据访问操作是执行定义在* 道接口.这个定义假设接口被放置在* "dao" 包,实现类型在子包中.*/@Pointcut("执行(* com.xyz.someapp.dao.*.*(..))")public void dataAccessOperation() {}}

通过这种方式,您未来可能需要的任何方面都可以重用整个系统架构方法,并与应用它们的实际模块一起使用.

I have an aspect com.x.NiceAspect in one maven project module, and a class com.x.NiceClass in a separate maven module. Those modules have the same POM parent, together creating one project.

The thing I am trying to achieve is to have a universal aspect that I can include in all my maven modules in this project.

Now the pointcut in the NiceAspect is i.e. execution(* com.x...set(..)) meaning all setter methods in mine package.

I want this aspect to run with the second module, especially to join NiceClass

How can I achieve this?

Moreover suppose that the Aspect wants an argument of a class that's defined in that second module, then I end up with a circular dependency..

Any help appreciated

Kind regards,

x.

解决方案

  • I want this aspect to run with the second module, especially to join NiceClass

    If the pointcut matches a method from "another" module, the aspect will apply. You need to do nothing special, besides setting your dependencies correctly. e.g have your AOP configuration globally imported.

  • Moreover suppose that the Aspect wants an argument of a class that's defined in that second module, then I end up with a circular dependency..

    The aspect dependency on the class argument should not result in circular dependency, since you have a parent POM that connects the two, and at runtime both of the modules are in a classpath.

In general, it is recommended to follow Aspect structure as described by Spring documentation => create an overall SystemArchitecture aspect, and then add more narrowed scope aspects as needed:

@Aspect
public class SystemArchitecture {

  /**
   * A join point is in the web layer if the method is defined
   * in a type in the com.xyz.someapp.web package or any sub-package
   * under that.
   */
  @Pointcut("within(com.xyz.someapp.web..*)")
  public void inWebLayer() {}

  /**
   * A join point is in the service layer if the method is defined
   * in a type in the com.xyz.someapp.service package or any sub-package
   * under that.
   */
  @Pointcut("within(com.xyz.someapp.service..*)")
  public void inServiceLayer() {}

  /**
   * A join point is in the data access layer if the method is defined
   * in a type in the com.xyz.someapp.dao package or any sub-package
   * under that.
   */
  @Pointcut("within(com.xyz.someapp.dao..*)")
  public void inDataAccessLayer() {}

  /**
   * A business service is the execution of any method defined on a service
   * interface. This definition assumes that interfaces are placed in the
   * "service" package, and that implementation types are in sub-packages.
   * 
   * If you group service interfaces by functional area (for example, 
   * in packages com.xyz.someapp.abc.service and com.xyz.def.service) then
   * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))"
   * could be used instead.
   *
   * Alternatively, you can write the expression using the 'bean'
   * PCD, like so "bean(*Service)". (This assumes that you have
   * named your Spring service beans in a consistent fashion.)
   */
  @Pointcut("execution(* com.xyz.someapp.service.*.*(..))")
  public void businessService() {}

  /**
   * A data access operation is the execution of any method defined on a 
   * dao interface. This definition assumes that interfaces are placed in the
   * "dao" package, and that implementation types are in sub-packages.
   */
  @Pointcut("execution(* com.xyz.someapp.dao.*.*(..))")
  public void dataAccessOperation() {}

}

This way any future aspects you may need, can reuse the over all System Architecture approach as well as live together with the actual module they are applied to.

这篇关于单独模块中使用的 Spring AOP 方面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆