AspectJ が Spring の @Configurable をコンパイル時に織り込む機能が機能しないのはなぜですか?
-
05-09-2019 - |
質問
アップデート 5: 最新の Eclipse に基づいた最新の Spring ToolsSuite IDE をダウンロードしました。プロジェクトを Maven プロジェクトとしてインポートすると、Eclipse/STS はプロジェクトのビルドに Maven ゴールを使用しているように見えます。これは、AspectJ が最終的に Eclipse で正しく動作することを意味します。
アップデート 4: 私は結局、コンパイル時のウィービングに Maven + AspectJ プラグインを使用するだけで、Eclipse のメカニズムを効果的にバイパスすることになりました。
アップデート 3: AspectJ の Eclipse プラグインは、Tomcat に正しくパブリッシュする Eclipse の機能を妨げているようです。プロジェクトの 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 に関しては、織り込みたいバイナリの側面を取り込むことで、ある程度の進歩を遂げました - この場合 spring-aspects.jar - そしてそれをクラスパスからコピーします。次に、この外部 jar を自分のファイルに追加します アスペクトパス. 。これを実行すると、Eclipse はコード内に AspectJ マーカーを適切に表示します。離れられないのが面倒だ spring-aspects.jar 私の中で Java ビルド パス これは、Maven プラグインを介して Maven によって維持されます。ただし、何らかの理由で、AspectJ プラグインは、バイナリ アスペクトが明示的に追加されない限り、バイナリ アスペクトを認識しません。 アスペクトパス.
元の投稿: @Configurable は、Spring の外部 (たとえば、Hibernate または一部の Factory クラス) でインスタンス化されたオブジェクトに依存関係を注入できるようにする Spring アノテーションです。
以前にこのアノテーションをロードタイムウィービングで使用していましたが、 たいてい 働きました。時々、起動しても何も注入されないことがありました。この問題が発生しました この StackOverflow の質問. 。回答はそれほど多くありませんでしたが、信頼性がより高いため、代わりにコンパイル時ウィービングを試すことを提案する人がほとんどでした。
Eclipse と Maven 用の AspectJ プラグインをインストールしました。これらはどちらも、適切にコンパイルされたように見えるクラスを生成します。AspectJ をコンパイルする前にテキスト エディタでクラスの 1 つを開いたところ、AspectJ への参照が見つかりませんでした。AspectJ のコンパイル後にそれを開くと、Eclipse と Maven で生成されたバージョンの両方にへの参照があります。 org.aspectj.weaver.MethodDeclarationLineNumber. 。このため、適切にコンパイルされていると思われます。問題は、一度デプロイすると依存関係が注入されないことです。
私の春 applicationContext.xml 以下が含まれます。
<context:spring-configured />
<context:component-scan base-package="com.myapp" />
DI を行うために @Configurable とマークされたクラスに必要なのは上記のすべてですか?ロード時ウィービングからコンパイル時ウィービングへの変換中に、 META-INF/aop.xml, <context:load-time-weaver /> 私から applicationContext.xml, 、そして私の Spring の Tomcat ウィーバー context.xml.
この問題をさらに詳しく調査するにはどうすればよいですか?考えられる原因は何ですか?
解決
コンパイル時ウィービングを使用する 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>
これは 2 つの別々の実行ステップとして実行され、単体テストとコンパイル用に異なるアスペクト ライブラリを追加できるようになります。
Spring-aspects ライブラリに次の依存関係を追加することも必要です。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<scope>compile</scope>
</dependency>
他のヒント
これが代替手段である場合、アプリでロード時間ウィービングを正常に構成できました。
私の環境:
- JDK-1.6
- 春-2.5.6
- eclipselink-1.1.0を使用したJPA
構成の詳細:
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>
春の注釈
@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 によって作成されます。baseEntittyのhistoryHandlerとhistoryHandlerのhistoryDaoはload-timeweavingによって設定されます。
VM パラメータは、Eclipse 実行構成または Tomcats catalina.sh/bat で設定できます。
@configurable クラスのフィールドを作成する このアノテーションに対してスプリングを適切に構成しない場合、Autowired は NullPointerException をスローします。@configurable アノテーションを適切に機能させるには、次の手順に従ってください。
このメソッドはと呼ばれます Spring Bean を非 Spring 製クラスに注入するための AspectJ ビルド時ウィービング.
最初のステップは、これらのプラグインを Eclipse にインストールすることです。
これら 2 つの更新サイトから、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>
重要: 絶対に使用しないでください <pluginManagment>
下のタグ <build>
鬼ごっこ。pom.xml は次のようにする必要があります。
<project ....>
....
<dependencies>
<dependency>
....
</dependency>
....
</dependencies>
<build>
<plugins>
<plugin>
....
</plugin>
....
</plugins>
</build>
</project>
最後に追加します <context:spring-configured />
Spring アプリケーションのコンテキスト構成ファイルに追加します。
POJO クラスに次のように注釈を付けることができるようになりました。 @Configurable
春の豆をそれに注入します @Autowired
注釈。こうすることで、その POJO の新しいインスタンスを作成するたびに、そのインスタンスが構成されます (例:依存関係が挿入されます) が自動的に挿入されます。
Eclipse のクラスパスの問題に関する限り、これは役に立つかもしれません。
の m2eclipseプラグイン オプションがあります AJDTの統合. 。この統合は、aspectj-maven-plugin 構成の aspectLibraries セクションを読み取り、jar を Eclipse の Aspect Path に提供します。