簡體   English   中英

服務bean無法在spring cglib代理中注入

[英]Service bean failed to inject in spring cglib proxy

我有一個注釋

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PartnerProxy {
}

和建議

@Component
@Aspect
public class AnnotationAdvice {

    @Around("@annotation(PartnerProxy)")
    public Object pc(ProceedingJoinPoint joinPoint) throws Throwable {
        return joinPoint.proceed();
    }
}

而我想要代理的bean

public class OuterServiceProxy {

    private IRoomStatusService service;
    ... another properties

    String getRemoteHourRoomStatus(){
        return service.echo();
    }
    @PartnerProxy
    public void hello() {
    }
    ...getters & setters

有一個屬性IRoomStatusService service ,這是重點。 首先,如果我在spring xml文件中聲明OuterServiceProxy

<bean id="outerServiceProxy" class="aop.jg.OuterServiceProxy">
        <property name="service" ref="service"/>
    </bean>

outerServiceProxy.getRemoteHourRoomStatus()方法時,拋出了一個NPE。 我調試到那一行[1]

String getRemoteHourRoomStatus(){
        return service.echo();  [1]
    } 

service為空。 但是outerServiceProxyOuterServiceProxy$$EnhancerByCGLIB$$b0b63bb6實際上是由Cglib增強的,但似乎outerServiceProxy只是直接調用String getRemoteHourRoomStatus()而不是通過回調並調用TargetSource,所以service是null。 但那毫無意義!

當我添加public修飾符時, public String getRemoteHourRoomStatus()一切正常。

更奇怪的是,沒有public修改器,我的PC中的代碼相同,但NPE在公司測試環境中拋出。

下面是訣竅:如果覆蓋類由與定義重寫方法的類相同的ClassLoader加載,則VM僅考慮重寫的包私有方法。

這意味着對於兩個具有重寫的包私有方法的類,例如:

public class Foo { String qux() { return "foo"; } }
public class Bar extends Foo { @Override String qux() { return "bar"; } }

哪里

Foo.class.getClassLoader() != Bar.class.getClassLoader()

持有,可以觀察到以下行為:

Foo foo = new Bar();
assertThat(foo.qux(), is("foo"));
assertThat(((Bar) foo).qux(), is("bar"));

原因是運行時包不相等,因此,不同運行時包的包私有方法不會相互覆蓋。 這不是cglib的限制,而是JVM的規范細節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM