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

Rob*_*ell 25 java aop spring-aop compile-time-weaving maven

更新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>
Run Code Online (Sandbox Code Playgroud)

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

关于Eclipse,我通过采用我想编织的二进制方面取得了一些进展 - 在本例中是spring-aspects.jar - 并将其复制出我的类路径.然后我将这个外部jar添加到我的Aspect Path中.执行此操作后,Eclipse在我的代码中正确显示了AspectJ标记.令人讨厌的是,我不能将spring-aspects.jar留在我的Java Build Path中,这是由Maven通过Maven插件为我维护的.但是,出于某种原因,除非将AspectJ插件显式添加到Aspect Path,否则AspectJ插件不会看到二进制方面.


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

我以前使用这个注释与加载时编织,它主要工作.偶尔我会启动,没有任何东西会被注入.这个问题催生了这个StackOverflow问题.答案并不多,但大多数人建议我尝试编译时编织,因为可靠性更高.

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

My Spring applicationContext.xml确实包含以下内容:

    <context:spring-configured />

    <context:component-scan base-package="com.myapp" />
Run Code Online (Sandbox Code Playgroud)

以上所有标记为@Configurable的类都需要完成DI吗?在从加载时编织到编译时编织的转换过程中,我从applicationContext.xml中删除了META-INF/aop.xml,<context:load-time-weaver />,从我的context.xml中删除了Spring的Tomcat编织器.

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

小智 26

它使用编译时编织为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>
Run Code Online (Sandbox Code Playgroud)

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

您还需要为spring-aspects库添加以下依赖项:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <scope>compile</scope>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

  • 您需要将<complianceLevel> 1.6 </ complianceLevel>添加到aspectj-maven-plugin配置,否则它会根据错误消息以错误(configure.incompatibleComplianceForSource)结束,因为complianceLevel默认为1.4并且它与源设置1.6不同在你的情况下 (3认同)

uı6*_*uɐp 7

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

我的环境:

  • JDK-1.6
  • 弹簧2.5.6
  • JPA与eclipselink-1.1.0

配置细节:

Spring 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>
Run Code Online (Sandbox Code Playgroud)

春天注释

@Configurable("baseEntity")
public abstract class BaseEntity

@Configurable("historyHandler")
public class HistoryJpaHandler extends SessionEventAdapter implements HistoryHandler 
Run Code Online (Sandbox Code Playgroud)

Java VM参数

<JAVA_HOME>/bin/java -javaagent:/full/path/to/spring-agent-2.5.6.jar
Run Code Online (Sandbox Code Playgroud)

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

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