更新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>
我实际上担心我会重复this problem,其中一切都不一致。随着我了解更多信息,我会更新此问题。
关于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类)。
我以前使用此注释进行加载时编织,而主要是工作。偶尔我会启动,没有任何东西会被注入。这个问题催生了this StackOverflow question。答案不多,但大多数人建议我尝试编译时编织,因为可靠性更高。
我为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" />
以上所有标记为@Configurable的类都需要完成DI吗?在从加载时编织到编译时编织的转换过程中,我删除了 META-INF / aop.xml ,&lt; context:load-time-weaver /&gt; 来自我的 applicationContext.xml ,以及我的 context.xml 中的Spring的Tomcat编织器。
如何进一步调查此问题?可能的原因是什么?
答案 0 :(得分: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>
它作为两个单独的执行步骤完成,允许您为单元测试和编译添加不同的方面库。
您还需要为spring-aspects库添加以下依赖项:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<scope>compile</scope>
</dependency>
答案 1 :(得分:7)
我在我的应用中成功配置了加载时编织,如果这是您的替代方案。
我的环境:
配置详情:
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>
Spring注释
@Configurable("baseEntity")
public abstract class BaseEntity
@Configurable("historyHandler")
public class HistoryJpaHandler extends SessionEventAdapter implements HistoryHandler
Java VM参数
<JAVA_HOME>/bin/java -javaagent:/full/path/to/spring-agent-2.5.6.jar
historyHandler和baseEntitty的实例由ecliselink创建。 historyHandler in baseEntitty and historyDao in historyHandler是由load-timeweaving设置的。
您可以在Eclipse运行配置或Tomcats catalina.sh/bat中设置VM参数。
答案 2 :(得分:4)
创建@configurable类的字段Autowired会抛出NullPointerException。 按照以下步骤使@configurable注释正常工作
此方法称为 AspectJ构建时编织,以将spring bean注入非弹簧类。
第一步是在eclipse中安装这些插件:
从这两个更新站点安装eclipse建议的任何内容:
http://download.eclipse.org/tools/ajdt/43/update
http://dist.springsource.org/release/AJDT/configurator/
安装完成后,右键单击项目并执行:
Configure > Convert to Aspectj
Maven > Update
接下来,您需要将这些添加到您的pom.xml:
在依赖项下添加:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
在插件下添加:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.5</version>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<source>1.7</source>
<target>1.7</target>
<Xlint>ignore</Xlint>
<complianceLevel>1.7</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>false</verbose>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.7.0</version>
</dependency>
</dependencies>
</plugin>
重要提示:请勿在{{1}}标记下使用任何<pluginManagment>
标记。
你的pom.xml需要是这样的:
<build>
最后将<project ....>
....
<dependencies>
<dependency>
....
</dependency>
....
</dependencies>
<build>
<plugins>
<plugin>
....
</plugin>
....
</plugins>
</build>
</project>
添加到您的spring应用程序上下文配置文件中。
现在,您可以将POJO类注释为<context:spring-configured />
,并使用@Configurable
注释在其中注入spring bean。这样,无论何时创建该POJO的新实例,它都将自动配置(例如注入依赖项)。
答案 3 :(得分:2)
就Eclipse类路径问题而言,您可能会觉得这很有用。
m2eclipse plugin有一个可选的AJDT integration。该集成读取了aspectj-maven-plugin配置的aspectLibraries部分,并将jar提供给Eclipse的Aspect Path。