web-dev-qa-db-ja.com

Springの@ConfigurableのAspectJコンパイル時ウィービングが機能しないのはなぜですか?

アップデート5:最新のSpringToolsSuiteをダウンロードしましたIDE最新のEclipseに基づいています。プロジェクトをMavenプロジェクトとしてインポートすると、Eclipse/STSが使用しているように見えますプロジェクトを構築するためのMavenの目標これは、AspectJがEclipseで正しく機能することを意味します。

更新4: Eclipseのメカニズムを効果的にバイパスして、コンパイル時のウィービングにMaven + AspectJプラグインを使用することになりました。

更新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をMavenプラグインを介してMavenによって維持されているJavaビルドパスに残すことができないのは面倒です。ただし、何らかの理由で、AspectJプラグインは、バイナリアスペクトがアスペクトパスに明示的に追加されていない限り、バイナリアスペクトを認識しません。


Original Post: @ConfigurableはSpringアノテーションであり、Springの外部でインスタンス化されたオブジェクトに依存関係を注入できます(たとえば、Hibernateまたは一部のFactoryクラスによって)。

以前、このアノテーションをロード時のウィービングで使用していましたが、 mostly が機能しました。たまに起動して何も注入されないことがありました。この問題が発生しました このStackOverflowの質問 。答えはあまりありませんでしたが、信頼性が高いので、代わりにコンパイル時のウィービングを試してみることをお勧めします。

EclipseとMaven用のAspectJプラグインをインストールしました。これらは両方とも、適切にコンパイルされたクラスのように見えるものを生成します。 AspectJをコンパイルする前に、テキストエディタでクラスの1つを開いたところ、AspectJへの参照が見つかりませんでした。 AspectJのコンパイル後に開いたところ、EclipseとMavenの両方で生成されたバージョンにはorg.aspectj.weaver.MethodDeclarationLineNumberへの参照があります。これが、適切にコンパイルされていると私が思う理由です。問題は、一度デプロイされると、依存関係が注入されないことです。

私のSpring applicationContext.xml には次のものが含まれています。

    <context:spring-configured />

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

@ConfigurableとマークされたクラスがDIを実行するために必要なのは、上記のすべてですか?ロード時ウィービングからコンパイル時ウィービングへの変換中に、 META-INF/aop.xml <context:load-time-weaver/> applicationContext.xml から、SpringのTomcatウィーバーは context.xml から。

この問題をさらに調査するにはどうすればよいですか?考えられる原因は何ですか?

25
Robert Campbell

コンパイル時のウィービングを使用して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>
26
Stephen Houston

これが代替手段である場合は、アプリでロード時ウィービングを正常に構成しました。

私の環境:

  • 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>

春の注釈

@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実行構成またはTomcatcatalina.sh/batで設定できます。

このアノテーションに対してスプリングを適切に設定しないと、Autowiredが@configurableクラスのフィールドを作成すると、NullPointerExceptionがスローされます。次の手順に従って、@ configurableアノテーションが正しく機能するようにします

このメソッドはAspectJビルドタイムウィービングでSpring BeanをSpring製以外のクラスに注入すると呼ばれます。

最初のステップは、これらのプラグインを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注釈を使用してSpring Beanを注入できます。このようにして、そのPOJOの新しいインスタンスを作成するたびに、自動的に構成されます(たとえば、依存関係が挿入されます)。

4
Meysam Feghhi

Eclipseクラスパスの問題に関する限り、これが役立つ場合があります。

m2Eclipseプラグイン にはオプションの AJDT統合 があります。統合は、aspectj-maven-pluginの構成のaspectLibrariesセクションを読み取り、Eclipseのアスペクトパスにjarを提供します。

2
Rich Seller