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



我正在处理一个由许多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注释)提供事务行为(用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;
  }
  ...
}

或者一个抽象的Base DAO,应用程序的其余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进行构建,并在JBossEAP 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'
 ...

但是当在内部启动EAR时,BaseDAO类被完全忽略:

 ...
 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中。项目中的每一场战争都有自己的jboss-deployment-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丢失了,因此类加载器以一种非常不同的方式工作,从而产生了我在问题中提出的问题。只需在EAR的META-INF中放入jboss-deployment-structure.xml(EAR,即WAR的组合)就解决了这个问题。

希望这能帮助到有类似问题的人。

最新更新