Service bean failed to inject in spring cglib proxy

痞子三分冷 提交于 2019-12-22 10:35:40

问题


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

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. firstly if i declare OuterServiceProxy in spring xml file

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

and when outerServiceProxy.getRemoteHourRoomStatus() method is called, An NPE was thrown. I debug to that line [1]

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

service is null. 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. But that make no sense!

When i add public modifier, public String getRemoteHourRoomStatus() everything goes fine.

And even more strange thing is that without public modifer, same code goes well in my PC, but NPE thrown in company testing environment.


回答1:


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.

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.



来源:https://stackoverflow.com/questions/35135499/service-bean-failed-to-inject-in-spring-cglib-proxy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!