AspectJ 加载时间 Weaving 在部署的 EAR 中无法正常工作 类

AspectJ load time Weaving not working properly within EAR deployed classes

我正在处理一个由许多 WAR 文件组成的多模块项目。这些项目使用 Spring 4.0.5 来管理依赖项,并使用 AspectJ 1.8.5 和加载时间编织来支持 AOP(Spring 基本 AOP 支持在这个项目中还不够)。另外,META-INF目录下有一个aop.xml,配置很简单:

<aspectj>
  <aspects>
   <!--No need to specify any aspect here-->
  </aspects>
  <weaver options="-XnoInline -verbose">
    <include within="com.myproject..*" />   
  </weaver>
</aspectj>

AOP 主要用于提供各种服务和DAO(用@Service 和@Repository 标注),具有Transactional 行为(用spring 的@Transactional 标注)。例如:

@Service(value = "alertService")
public class AlertServiceImpl implements IAlertService, Serializable {
  ...
  @Transactional(rollbackFor = Exception.class)
  @Override
  public Alert createAlert(Alert alert) {
    alertDAO.create(alert);
    return alert;
  }
  ...
}

或者应用程序的其余 DAO 继承的抽象 Base DAO

@Repository
public abstract class BaseDAO<E extends IBusinessObject, PK extends Serializable> {
  ...
  @Transactional(readOnly = true)
  public <C extends E> C findFirstByFields(Class<C> type, String[] fields, Object[] values, String[] dependencies)
      throws ModelException {
    List<C> list = findAllByFields(type, fields, values, null, null, 1, null);
    if (list.isEmpty()) {
      return null;
    } else {
      C obj = list.get(0);
      loadDependencies(obj, dependencies);
      return obj;
    }
  }
  ...
}

最终项目使用 maven 构建并在 JBoss EAP 6.1 上运行。

因此,使用此配置,在构建和部署 WAR 文件时一切正常。但是,如果我仅使用其中一个 WAR 文件构建一个简单的 EAR 文件,则加载时间编织会编织除一个 BaseDAO 之外的所有类。

我已经为此苦苦挣扎了很多时间,我唯一能得到的是在应用程序启动时,编织在两种情况下几乎相同,除了在 EAR 中,BaseDAO 没有编织。我不知道为什么。知道为什么会这样吗?

P.D.: 从 WAR:

启动应用程序时,启用 AspectJ 编织日志会显示此信息
 ...
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure1'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure3'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure5'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.services.Repository$AjcClosure1'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure1'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure3'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure5'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.model.dao.BaseDAO$AjcClosure7'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.model.dao.LastDocumentNumberDAO$AjcClosure1'
 ...

但是当用这个 war 启动 EAR 时,BaseDAO class 被完全忽略:

 ...
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure1'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure3'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.commons.services.CommonService$AjcClosure5'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.services.Repository$AjcClosure1'
 ServerService Thread Pool -- 227 ? [ModuleClassLoader@1b3a9e75] debug generating class 'com.myproject.subproject.model.dao.LastDocumentNumberDAO$AjcClosure1'
 ...

终于找到问题所在了。它在 jboss-deployment-structure.xml 中。 项目中的每个 war 都有自己的 jboss-部署-structure.xml,但有一些例外:

<jboss-deployment-structure>
  <deployment>
    <!-- Exclusions allow you to prevent the server from automatically adding some dependencies -->
    <exclusions>
      <module name="org.apache.log4j" />
      <module name="org.slf4j" />
      <module name="org.apache.commons.logging" />
      <module name="org.log4j" />
      <module name="org.jboss.logging" />
      <module name="org.javassist" />
      <module name="org.hibernate.validator" />
      <module name="org.jboss.ws.cxf" />
    </exclusions>
    <exclude-subsystems>
      <subsystem name="webservices" />
    </exclude-subsystems>
  </deployment>
</jboss-deployment-structure>

但是在 EAR 部署中,EAR 的特定 jboss-deployment-structure.xml 丢失了,所以类加载器以非常不同的方式工作,造成了我 post 在我的问题。只需将 jboss-deployment-structure.xml(EAR 部署,即 WAR 的组合)放入 EAR 的 META-INF 中即可解决问题。

希望这对遇到类似问题的人有所帮助。