Java AspectJ和Spring LTW没有';向上浇铸时不工作
我用AspectJ和spring快速成功地设置了LTW。以下是设置: beans.xml:Java AspectJ和Spring LTW没有';向上浇铸时不工作,java,spring,aspectj,load-time-weaving,Java,Spring,Aspectj,Load Time Weaving,我用AspectJ和spring快速成功地设置了LTW。以下是设置: beans.xml: <context:annotation-config /> <aop:aspectj-autoproxy /> <context:spring-configured /> <context:load-time-weaver /> <context:component-scan base-package="com.test.service" />
<context:annotation-config />
<aop:aspectj-autoproxy />
<context:spring-configured />
<context:load-time-weaver />
<context:component-scan base-package="com.test.service" />
父类:
public class Bar {
}
可配置类,用于自动连接服务和扩展条
@Configurable
public class BarExtended extends Bar{
@Autowired
private MyService service;
public MyService getWeavedInObject(){
return service;
}
}
而只是一个引用了父类栏的类:
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类时(因此不需要向上转换):
上述测试将起作用。当一个可配置对象被上溯时,有人知道为什么AspjectJ的行为如此奇怪吗
编辑:以下操作也失败:
@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忽略。
但使用反射来实例化未扩展的作品:
@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());
}
奇怪,不是吗
非常感谢
问候,
Andreas我过去认为LTW配置有问题,但这并不是因为我不太确定的原因。因此,我现在在配置中100%显式地对配置文件进行以下更改,看看是否一切正常
<context:load-time-weaver aspectj-weaving="on" />
从您的配置中删除
,您不需要它,因为您已经真正运行了LTW
当您运行JUnit测试时,您是否传递vm参数来告诉JUnit LTW代理在哪里?如果没有,那么您没有运行LTW
以下是文档中关于
为此应用程序上下文激活Spring LoadTimeWeaver,作为名为
“loadTimeWeaver”。任何实现LoadTimeWeaverAware接口的bean都将收到
LoadTimeWeaver自动参考;例如,Spring的JPA引导支持。默认的编织者是
自动确定。从Spring2.5开始:检测Sun的GlassFish、Oracle的OC4J、Spring的VM代理和
Spring的ReflectVeloadTimeweaver支持的任何类加载器(例如
TomcatInstrumentableClassLoader)。AspectJ加载时编织的激活是通过一个简单的
标志(“aspectj编织”属性),aspectj类转换器通过Spring的
LoadTimeWeaver。如果存在“META-INF/aop.xml”资源,默认情况下将激活AspectJ编织
在类路径中。这还会激活当前应用程序上下文,以便将依赖项注入应用到
在Springbean工厂之外实例化的非托管类(通常是带注释的类
使用@Configurable注释)。仅当AnnotationBeanConfigureSpect位于
类路径(即springaspects.jar),默认情况下有效激活“springconfigured”。有关详细信息,请参见Javadoc
org.springframework.context.annotation.EnableLoadTimeWeaving以获取基于代码的信息
引导加载时编织支持的替代方案
因此,总而言之,放置
似乎实际上是定义一个id为loadTimeWeaver的bean,并扫描类路径以查找像aop.xml这样的特殊文件,以确定是否应该打开aspectJ。要确保aspectJ已打开,您确实需要将aspectJ weaving=“on”
设置为该方式,如果它无法打开aspectJ,无论出于何种原因,启动时都会失败,这正是您想要的。在我的web应用程序中,我有一个在web应用程序启动时运行的测试,以确保aspectJ正在运行,如果不是,它会抱怨 我在JUnit设置中遇到了相同的问题,使用标准spring instrument设置。
当使用WebSphereLoadTimeWeaver在WebSphere容器中运行相同的代码时,没有任何问题
我的openJPA代码是增强的构建时代码。
我的@Configurable和其他一些方面都是在加载时完成的
我最好的猜测是openjpa继承策略的增强稍后会与LTW冲突,因此与@configurable结合使用时会出现一些空指针问题
JUNIT示例
AbstractX=新混凝土();//@他正在工作
Abstractx=新混凝土();
x、 callAnyMethod();//给出了openjpa抽象上的LTW问题,因此@Configurable不起作用
以上两个示例都在WebSphereEnv中工作
你解决过这个问题吗?你使用什么版本的Java、AspectJ?我使用Java 1.6、AspectJ 1.6.12和Spring 3.1.0.RELEASE。该死的,我也遇到了这个问题。我刚刚在他们的JIRA和可复制的测试用例中提出了这个问题:您解决过这个问题吗?我的日程排得很紧,谢谢你的长篇大论。设置explizit aspetj=“on”没有帮助。我还玩弄了aop.xml:并没有成功。这似乎真的是一个升级问题。
@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());
}
<context:load-time-weaver aspectj-weaving="on" />