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

发布于 2024-07-22 07:03:18 字数 2569 浏览 13 评论 0原文

更新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,我通过获取我想要编织的二进制方面(在本例中为 spring-aspects.jar)并将其从我的类路径中复制出来,取得了一些进展。 然后,我将这个外部 jar 添加到我的 Aspect Path 中。 完成此操作后,Eclipse 会正确显示代码中的 AspectJ 标记。 令人烦恼的是,我不能将 spring-aspects.jar 留在我的 Java 构建路径 中,该路径是由 Maven 通过 Maven 插件为我维护的。 然而,由于某种原因,AspectJ 插件看不到二进制方面,除非将它们显式添加到方面路径


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

我之前在加载时编织中使用过这个注释,它大部分都有效。 有时我会启动但没有任何东西被注入。 这个问题催生了这个 StackOverflow 问题。 答案并不多,但大多数人建议我尝试编译时编织,因为它具有更高的可靠性。

我安装了 Eclipse 和 Maven 的 AspectJ 插件。 这两者都会生成看起来正确编译的类。 在 AspectJ 编译之前,我在文本编辑器中打开了其中一个类,但没有发现对 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来自我的applicationContext.xml,以及来自我的context.xml的Spring Tomcat weaver。

我怎样才能进一步调查这个问题? 可能的原因有哪些?

Update 5: I've downloaded the latest Spring ToolsSuite IDE based on the latest Eclipse. When I import my project as a Maven project, Eclipse/STS appears to use the Maven goals for building my project. This means AspectJ finally works correctly in Eclipse.

Update 4: I have ended up just using Maven + AspectJ plugin for compile-time weaving, effectively bypassing Eclipse's mechanism.

Update 3: It seems AspectJ's Eclipse plug-in breaks Eclipse's ability to correctly Publish to Tomcat. Only by removing the AspectJ capability on a project can I get it to properly Publish again. Very annoying.

Update 2: I have this now working in Eclipse. It makes me very uncomfortable to say this, but I have no idea how I got it working from either Eclipse or Maven builds. It appears to be a compile issue rather than a run-time issue.

Update 1: It appears I've gotten this to work via Maven builds, but I have no idea how. Eclipse still doesn't work. The only thing I changed in the pom.xml was adding these (insignificant?) configuration parameters:

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

I'm actually worried that I have a repeat of this problem, where everything works inconsistently. I will keep this question updated as I learn more.

With regards to Eclipse, I made some progress by taking the binary aspects I wish to weave - in this case spring-aspects.jar - and copying it out of my classpath. I then add this now external jar to my Aspect Path. After doing this, Eclipse properly shows me AspectJ markers in my code. It's annoying that I can't just leave spring-aspects.jar in my Java Build Path which is maintained by Maven for me via the Maven plug-in. For some reason, however, the AspectJ plug-in doesn't see the binary aspects unless they're explicitly added to the Aspect Path.


Original Post: @Configurable is a Spring annotation that allows dependencies to be injected into objects instantiated external to Spring (for example, by Hibernate or some Factory class).

I was using this annotation previously with load-time weaving and it mostly worked. Occasionally I would boot up and nothing would get injected. This issue spawned this StackOverflow question. There weren't many answers, but most suggested that I try compile-time weaving instead due to greater reliability.

I installed the AspectJ plug-in for Eclipse and Maven. Both of these produce what appears to be properly compiled classes. I've opened up one of the classes in a text editor before AspectJ compilation and found no references to AspectJ. I opened it up after AspectJ compilation and both Eclipse and Maven generated versions have a reference to org.aspectj.weaver.MethodDeclarationLineNumber. This is why I assume it's being properly compiled. The problem is that once deployed, no dependencies get injected.

My Spring applicationContext.xml does include the following:

    <context:spring-configured />

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

Is the above all that's needed for classes marked @Configurable to have DI done? During the conversion from load-time weaving to compile-time weaving, I removed META-INF/aop.xml, <context:load-time-weaver /> from my applicationContext.xml, and Spring's Tomcat weaver from my context.xml.

How can I investigate this problem further? What are possible causes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

岁月打碎记忆 2024-07-29 07:03:18

它适用于我们在 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>

It works for us on maven using compile time weaving, try adding the following plugins:

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

Its done as two separate execution steps to allow you to add different aspect libraries for unit testing and compilation.

You'll also need the following dependency added for the spring-aspects library:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <scope>compile</scope>
    </dependency>
终弃我 2024-07-29 07:03:18

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

我的环境:

  • JDK-1.6
  • Spring-2.5.6
  • JPA with 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>

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创建。 baseEntitty 中的historyHandler 和historyHandler 中的historyDao 是通过load-timeweaving 设置的。

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

I successfully configured load-time weaving in my app, if this is an alternative for you.

My environment:

  • JDK-1.6
  • Spring-2.5.6
  • JPA with eclipselink-1.1.0

Configuration details:

Spring XML configuration:

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

@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

Instances of historyHandler and baseEntitty are created by ecliselink. historyHandler in baseEntitty and historyDao in historyHandler is set by load-timeweaving.

You can set the VM Parameter in Eclipse run configuration or in Tomcats catalina.sh/bat.

眼眸 2024-07-29 07:03:18

如果您没有为此注释正确配置 spring,则创建 @configurable 类 Autowired 的字段会抛出 NullPointerException。
按照以下步骤使 @configurable 注释正常工作。

此方法称为AspectJ 构建时编织,将 spring bean 注入到非 spring 制作的类

第一步是在 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>

重要:请勿在 < 下使用任何 标记/代码> 标签。
你的 pom.xml 需要是这样的:

<project ....>
    ....
    <dependencies>
        <dependency> 
                    ....
        </dependency>
                ....
    </dependencies>
    <build>
        <plugins>
            <plugin>
                            ....
            </plugin>
                        ....
        </plugins>
    </build>
</project>

最后将 添加到你的 spring 应用程序上下文配置文件中。

现在,您可以将 POJO 类注释为 @Configurable 并使用 @Autowired 注释在其中注入 spring beans。 这样,每当您创建该 POJO 的新实例时,它都会自动配置(例如注入依赖项)。

making a field of a @configurable class Autowired throws NullPointerException if you do not configure your spring properly for this annotation.
follow these steps to make @configurable annotations work properly

This method is called AspectJ build time weaving to inject spring beans to your non-spring-made classes.

First step is to install these plugins in eclipse:

From these two update sites install whatever eclipse suggests:

http://download.eclipse.org/tools/ajdt/43/update
http://dist.springsource.org/release/AJDT/configurator/ 

After installing,right-click on project and Do:

Configure > Convert to Aspectj
Maven > Update

Next, you need to add these to your pom.xml:

Under Dependencies Add:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>4.0.2.RELEASE</version>
</dependency>

Under Plugins Add:

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

Important: DO NOT use any <pluginManagment> tag under <build> tag.
your pom.xml needs to be something like this:

<project ....>
    ....
    <dependencies>
        <dependency> 
                    ....
        </dependency>
                ....
    </dependencies>
    <build>
        <plugins>
            <plugin>
                            ....
            </plugin>
                        ....
        </plugins>
    </build>
</project>

finally add <context:spring-configured /> to your spring application context config file.

Now you can annotate a POJO class as @Configurable and inject spring beans in it using @Autowired annotation. this way whenever you make a new instance of that POJO it will be configured (e.g. injected with dependencies) automatically.

再浓的妆也掩不了殇 2024-07-29 07:03:18

就您的 Eclipse 类路径问题而言,您可能会发现这很有用。

m2eclipse 插件 有一个可选的 AJDT 集成。 集成读取aspectj-maven-plugin 配置的aspectLibraries 部分,并将jar 贡献给Eclipse 的Aspect Path。

As far as your Eclipse classpath issues are concerned, you might find this useful.

The m2eclipse plugin has an optional AJDT integration. The integration reads the aspectLibraries section of the aspectj-maven-plugin's configuration, and contributes the jars to Eclipse's Aspect Path.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文