为什么AspectJ编译时编织Spring的@Configurable不起作用?

更新 5:我已经下载了基于最新Eclipse的最新Spring ToolsSuite IDE。当我将我的项目作为 Maven 项目导入时,Eclipse/STS 似乎使用 Maven 目标来构建我的项目。这意味着AspectJ终于在Eclipse中正常工作了。

更新 4:我最终只使用Maven + AspectJ插件进行编译时编织,有效地绕过了Eclipse的机制。

更新 3:AspectJ的Eclipse插件似乎破坏了Eclipse正确发布到Tomcat的能力。只有通过删除项目上的AspectJ功能,我才能让它再次正确发布。很烦人。

更新 2:我现在在Eclipse中工作了。说这句话让我非常不舒服,但我不知道我是如何从Eclipse或Maven构建中工作的。这似乎是编译问题,而不是运行时问题。

更新 1:看来我已经通过Maven构建实现了这一点,但我不知道如何操作。Eclipse仍然不起作用。我在pom.xml中唯一更改的是添加这些(微不足道的?)配置参数:

<source>1.6</source>
<complianceLevel>1.6</complianceLevel>
<verbose>true</verbose>
<showWeaveInfo>true</showWeaveInfo>
<outxml>true</outxml>

我实际上担心我会重复这个问题,一切都不一致。随着我了解更多,我会不断更新这个问题。

关于Eclipse,我取得了一些进展,我采用了我希望编织的二进制方面 - 在这种情况下.jar弹簧方面 - 并将其从我的类路径中复制出来。然后,我将这个现在的外部jar添加到我的Aspect Path中。完成此操作后,Eclipse在我的代码中正确地向我显示了AspectJ标记。令人讨厌的是,我不能只留下弹簧方面.jar在我的Java Build Path中,该路径由Maven通过Maven插件为我维护。但是,由于某种原因,AspectJ 插件看不到二进制方面,除非它们被显式添加到方面路径中。


原始帖子:@Configurable是一个Spring注释,允许将依赖项注入到Spring外部实例化的对象中(例如,通过Hibernate或某些Factory类)。

我以前在加载时间编织中使用了这个注释,它基本上有效。偶尔我会启动,什么也不会被注射。这个问题催生了这个StackOverflow问题。答案并不多,但大多数人建议我尝试编译时编织,因为可靠性更高。

我为Eclipse和Maven安装了AspectJ插件。这两者都生成看似正确编译的类。在AspectJ编译之前,我已经在文本编辑器中打开了其中一个类,但没有发现对AspectJ的引用。我在AspectJ编译后打开了它,Eclipse和Maven生成的版本都有对org.aspectj.weaver.MethodDeclarationLineNumber的引用。这就是为什么我认为它正在被正确编译。问题是,一旦部署,就不会注入任何依赖项。

我的Spring应用程序Context.xml包括以下内容:

    <context:spring-configured />

    <context:component-scan base-package="com.myapp" />

上述是否满足标记为@Configurable的类完成DI所需的全部内容?在从加载时编织到编译时编织的转换过程中,我从我的应用程序Context.xml中删除了META-INF / aop.xml<context:load-time-weaver />,并从我的上下文中删除了Spring的Tomcat编织器.xml

如何进一步调查此问题?可能的原因是什么?


答案 1

它适用于我们使用编译时编织的maven,请尝试添加以下插件:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
    <compilerVersion>1.6</compilerVersion>
    <fork>true</fork>
    <source>1.6</source>
    <target>1.6</target>
</configuration>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<executions>
    <execution>
        <id>compile</id>
        <configuration>
            <source>1.6</source>
            <target>1.6</target>
            <verbose>false</verbose>
            <outxml>true</outxml>
            <aspectLibraries>
                <aspectLibrary>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-aspects</artifactId>
                </aspectLibrary>
            </aspectLibraries>
        </configuration>
        <goals>
            <goal>compile</goal>
        </goals>
    </execution>
    <execution>
        <id>test-compile</id>
        <configuration>
            <source>1.6</source>
            <target>1.6</target>
            <verbose>false</verbose>
            <aspectLibraries>
                <aspectLibrary>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-aspects</artifactId>
                </aspectLibrary>
            </aspectLibraries>
        </configuration>
        <goals>
            <goal>test-compile</goal>
        </goals>
    </execution>
</executions>
<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.4</version>
    </dependency>
</dependencies>
</plugin>

它作为两个单独的执行步骤完成,允许您为单元测试和编译添加不同的方面库。

您还需要为弹簧方面库添加以下依赖项:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <scope>compile</scope>
    </dependency>

答案 2

我在我的应用程序中成功配置了加载时间编织,如果这是你的替代方案。

我的环境:

  • JDK-1.6
  • 春季-2.5.6
  • JPA with eclipselink-1.1.0

配置详细信息:

弹簧 XML 配置:

<context:annotation-config/>
<context:spring-configured/>
<context:load-time-weaver/>

<bean id="baseEntity" class="package.name.BaseEntity" scope="prototype">
  <property name="historyHandler" ref="historyHandler" />
</bean>

<bean id="historyHandler" class="package.name.HistoryJpaHandler" scope="prototype">
  <property name="historyDao" ref="historyDao" />
</bean>

<bean id="historyDao" class="package.name.HistoryJpaDao">
  <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

弹簧注释

@Configurable("baseEntity")
public abstract class BaseEntity

@Configurable("historyHandler")
public class HistoryJpaHandler extends SessionEventAdapter implements HistoryHandler 

Java VM Parameter

<JAVA_HOME>/bin/java -javaagent:/full/path/to/spring-agent-2.5.6.jar

historyHandler 和 baseEntitty 的实例由 ecliselink 创建。historyHandler in baseEntitty 和 historyDao in historyHandler 由 load-timeweaving 设置。

您可以在 Eclipse 运行配置或 Tomcats catalina.sh/bat 中设置 VM 参数。


推荐