2

我用 AspectJ 设置了 LTW,并且很快就成功了。这是设置:bean.xml:

<context:annotation-config />
<aop:aspectj-autoproxy />
<context:spring-configured />
<context:load-time-weaver />
<context:component-scan base-package="com.test.service" />

我的服务将自动连接到一个类:

@Service
public class MyService {
}

父类:

public class Bar {
}

可配置类,自动装配服务并扩展 Bar。

@Configurable
public class BarExtended extends Bar{
    @Autowired
    private MyService service;
    public MyService getWeavedInObject(){
        return service;
    }
}

并且只是一个引用了父类 Bar 的类:

public class Foo {
    private Bar bar;
    public void setBar(Bar bar) {
        this.bar = bar;
    }
}

和一个成功的测试用例。它只是创建一个 BarExtended 实例并检查 LTW 是否工作。Foo 类什么都不做。

@Test
public void simple(){
    Foo foo = new Foo();
    BarExtended barExtended = new BarExtended();
    assertNotNull("LTW didn't work.", barExtended.getWeavedInObject());
}

此测试以绿色运行。但以下测试失败:

@Test
public void simple(){
    Foo foo = new Foo();
    BarExtended barExtended = new BarExtended();
    foo.setBar(barExtended);
    assertNotNull("LTW didn't work.", barExtended.getWeavedInObject());
}

我只是插入将 BarExtended 类设置为 Foo 的行。沮丧使 AspjectJ 无法正常工作。

顺便说一句,当我将 Foo 类更改为使用 BarExtended 类时(因此不需要向上转换):

public class Foo {
    private BarExtended bar;
    public void setBar(BarExtended bar) {
        this.bar = bar;
    }
}

上述测试将起作用。有谁知道为什么 AspjectJ 在向上转换可配置对象时表现得如此奇怪?

编辑:Folwing 也失败了:

@Test
public void simple() {
    Foo foo = new Foo();
    BarExtended barExtended = new BarExtended();
    Bar bar = (Bar) new BarExtended();
    foo.setBar(bar);
    assertNotNull("LTW didn't work.", barExtended.getWeavedInObject());
}

一个不同的 BarExtended 对象被设置为 Foo 并且第一个 barExtended 对象被 AspectJ 忽略。但是使用反射来实例化 BarExtended 作品:

@Test
public void simple() throws InstantiationException, IllegalAccessException{
    Foo foo = new Foo();
    Bar barExtended = (Bar) BarExtended.class.newInstance();
    foo.setBar(barExtended);
    assertNotNull("LTW didn't work.", ((BarExtended)barExtended).getWeavedInObject());
}

奇怪,不是吗?

非常感谢

问候,

安德烈亚斯

4

2 回答 2

1

我在使用标准弹簧仪器设置的 JUnit 设置中遇到了同样的问题。当使用 WebSphereLoadTimeWeaver 在 WebSphere 容器中运行相同的代码时,没有任何问题!

我的 openJPA 代码增强了构建时间。我的@Configurable 和其他一些方面是在加载时间完成的。

我最好的猜测是,openjpa 继承策略的增强后来与 LTW 冲突,因此结合@Configuarable 给了我一些空指针问题。

JUNIT示例

AbstactWhatEver x = new Concrete(); // @Configurable 正在工作

AbstactWhatEver x = new Concrete(); x.callAnyMethod(); // 在 openjpa 抽象上给出 LTW 问题,因此 @Configurable 不起作用

上述两个示例都适用于 WEBSPHERE ENV。

你有没有解决过这个问题?

于 2014-01-16T07:37:07.220 回答
1

过去我曾遇到过问题,我认为 LTW 已配置,但这并不是因为我不太确定的原因。因此,我现在 100% 明确地在我的配置中对您的配置文件进行以下更改,看看是否一切正常。

  <context:load-time-weaver aspectj-weaving="on" />

从你的配置中删除<aop:aspectj-autoproxy />你不需要它你有 LTW 真正运行。

当您运行 JUnit 测试时,您是否传递了 vm 参数来告诉 JUnit LTW 代理在哪里?如果没有,那么您没有运行 LTW。

这是文档所说的<context:load-time-weaver />

为这个应用程序上下文激活一个 Spring LoadTimeWeaver,作为一个名为“loadTimeWeaver”的 bean 提供。任何实现 LoadTimeWeaverAware 接口的 bean 都会自动接收 LoadTimeWeaver 引用;例如,Spring 的 JPA 引导程序支持。默认编织器是自动确定的。从 Spring 2.5 开始:检测 Sun 的 GlassFish、Oracle 的 OC4J、Spring 的 VM 代理和 Spring 的 ReflectiveLoadTimeWeaver 支持的任何 ClassLoader(例如,TomcatInstrumentableClassLoader)。AspectJ 加载时编织的激活是通过一个简单的标志('aspectj-weaving' 属性)指定的,AspectJ 类转换器通过 Spring 的 LoadTimeWeaver 注册。如果“META-INF/aop. 这也激活了当前应用程序上下文,以将依赖注入应用到在 Spring bean 工厂之外实例化的非托管类(通常是使用 @Configurable 注释注释的类)。只有当 AnnotationBeanConfigurerAspect 位于类路径(即 spring-aspects.jar)时才会发生这种情况,默认情况下有效地激活“spring-configured”。有关引导加载时编织支持的基于代码的替代方法的信息,请参阅 org.springframework.context.annotation.EnableLoadTimeWeaving 的 Javadoc。这也激活了当前应用程序上下文,以将依赖注入应用到在 Spring bean 工厂之外实例化的非托管类(通常是使用 @Configurable 注释注释的类)。只有当 AnnotationBeanConfigurerAspect 位于类路径(即 spring-aspects.jar)时才会发生这种情况,默认情况下有效地激活“spring-configured”。有关引导加载时编织支持的基于代码的替代方法的信息,请参阅 org.springframework.context.annotation.EnableLoadTimeWeaving 的 Javadoc。

所以总而言之,put<context:load-time-weaver />似乎真的是关于定义一个id为loadTimeWeaver的bean并扫描类路径以查找aop.xml等特殊文件以确定是否应该打开aspectJ。为了确保 aspectJ 确实打开,aspectj-weaving="on"如果它无法打开 aspectJ,无论出于何种原因,它都会在启动时失败,这正是你想要的。在我的网络应用程序中,我有一个在网络应用程序启动时运行的测试,以确保 aspectJ 正在运行,如果不是,它会抱怨。

于 2012-07-02T08:51:51.033 回答