[英]Service bean failed to inject in spring cglib proxy
I have an annotation 我有一个注释
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PartnerProxy {
}
And a Advice 和建议
@Component
@Aspect
public class AnnotationAdvice {
@Around("@annotation(PartnerProxy)")
public Object pc(ProceedingJoinPoint joinPoint) throws Throwable {
return joinPoint.proceed();
}
}
And the bean i want to proxy 而我想要代理的bean
public class OuterServiceProxy {
private IRoomStatusService service;
... another properties
String getRemoteHourRoomStatus(){
return service.echo();
}
@PartnerProxy
public void hello() {
}
...getters & setters
there is a property IRoomStatusService service
, which is the point. 有一个属性
IRoomStatusService service
,这是重点。 firstly if i declare OuterServiceProxy
in spring xml file 首先,如果我在spring xml文件中声明
OuterServiceProxy
<bean id="outerServiceProxy" class="aop.jg.OuterServiceProxy">
<property name="service" ref="service"/>
</bean>
and when outerServiceProxy.getRemoteHourRoomStatus()
method is called, An NPE was thrown. 当
outerServiceProxy.getRemoteHourRoomStatus()
方法时,抛出了一个NPE。 I debug to that line [1] 我调试到那一行[1]
String getRemoteHourRoomStatus(){
return service.echo(); [1]
}
service
is null. service
为空。 But outerServiceProxy
is OuterServiceProxy$$EnhancerByCGLIB$$b0b63bb6
actually enhanced by Cglib, but it seems outerServiceProxy
just call String getRemoteHourRoomStatus()
directly and not through callback and call TargetSource, So service
is null. 但是
outerServiceProxy
是OuterServiceProxy$$EnhancerByCGLIB$$b0b63bb6
实际上是由Cglib增强的,但似乎outerServiceProxy
只是直接调用String getRemoteHourRoomStatus()
而不是通过回调并调用TargetSource,所以service
是null。 But that make no sense! 但那毫无意义!
When i add public modifier, public String getRemoteHourRoomStatus()
everything goes fine. 当我添加public修饰符时,
public String getRemoteHourRoomStatus()
一切正常。
And even more strange thing is that without public
modifer, same code goes well in my PC, but NPE thrown in company testing environment. 更奇怪的是,没有
public
修改器,我的PC中的代码相同,但NPE在公司测试环境中抛出。
Here is the trick: The VM only consideres a package-private method to be overridden if the overriding class is loaded by the same ClassLoader
as the class the defines the overridden method. 下面是诀窍:如果覆盖类由与定义重写方法的类相同的
ClassLoader
加载,则VM仅考虑重写的包私有方法。
This means that for two classes with overridden package-private methods such as: 这意味着对于两个具有重写的包私有方法的类,例如:
public class Foo { String qux() { return "foo"; } }
public class Bar extends Foo { @Override String qux() { return "bar"; } }
where 哪里
Foo.class.getClassLoader() != Bar.class.getClassLoader()
holds, the following behavior can be observed: 持有,可以观察到以下行为:
Foo foo = new Bar();
assertThat(foo.qux(), is("foo"));
assertThat(((Bar) foo).qux(), is("bar"));
The reasoning is that the runtime packages are not equal and therefore, the package-private methods of differing runtime packages do not override one another. 原因是运行时包不相等,因此,不同运行时包的包私有方法不会相互覆盖。 This is less a limitation of cglib than a specification detail of the JVM.
这不是cglib的限制,而是JVM的规范细节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.