简体   繁体   English

服务bean无法在spring cglib代理中注入

[英]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. 但是outerServiceProxyOuterServiceProxy$$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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM