Java Spring AOP CGLIB代理';s字段为空 描述

Java Spring AOP CGLIB代理';s字段为空 描述,java,spring,spring-aop,cglib,Java,Spring,Spring Aop,Cglib,使用该组件时,自定义组件将显示为AOP代理对象null的结果 媒体列表类 Spring配置类 AOP配置类 测试代码 方面类 Spring配置类 客户端类 公共类客户端{ 公共静态void main(字符串[]args){ AnnotationConfigApplicationContext上下文=新的AnnotationConfigApplicationContext(SpringConfig.class); TargetClass target=context.getBean(TargetC

使用该组件时,自定义组件将显示为AOP代理对象null的结果

媒体列表类 Spring配置类 AOP配置类 测试代码 方面类 Spring配置类 客户端类
公共类客户端{
公共静态void main(字符串[]args){
AnnotationConfigApplicationContext上下文=新的AnnotationConfigApplicationContext(SpringConfig.class);
TargetClass target=context.getBean(TargetClass.class);

System.out.println(“客户端调用:+target.test());//这是潜在意外行为的组合。首先,Spring使用CGLIB为AOP代理bean。CGLIB代理是类的动态子类型的实例,将所有方法调用委托给类的真实实例。但是,即使代理是子类型,其字段也不会初始化(即,未调用您的
TargetClass
超级构造函数)。可以找到更详细的解释

此外,您的方法

public final libvlc_media_list_t mediaListInstance() {
    return mediaListInstance; // <- proxy object return null, if use aop
}
因此,CGLIB无法重写它们以委托给实际实例。这将在Spring日志中得到暗示。例如,您将看到

22:35:31.773 [main] INFO  o.s.aop.framework.CglibAopProxy - Unable to proxy method [public final java.lang.String com.example.root.TargetClass.test()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
将以上所有内容放在一起,您将得到一个代理实例,其中字段为
null
,代理无法委托给实际实例的方法。因此,您的代码将实际调用

public final String test() {
    System.out.println("TargetClass.test();");
    return returnValue;
}
例如,
returnValue
字段为
null



如果可以,请更改您的方法,删除
final
修饰符。如果不能,您将不得不重新考虑您的设计。

请显示
mediaListInstance
的实现,并解释为什么它不应返回
null
。谢谢,添加了
mediaListInstance
的实现。我确信返回值是正确的当您不使用AOP时,值是正确的。我无法复制此值。请提供一个。再次感谢,添加了最小的示例。不幸的是,我无法更改它。但无论如何,谢谢您。因为我的
切入点
不是最终方法,而是其他方法。但是,由于代理对象无法代理最终方法,导致结果不正确lts.我可以将
ProceedingJoinPoint.getTarget()
作为要获取的目标对象,然后调用final方法吗?@fortream您不能。由于该方法是
final
,因此不会对其应用建议。
aroundTarget
不会为其调用。
@Aspect
public class MediaListAspect {
    @Pointcut("execution(* TestMediaList.xTest(..))")
    private void anyMethod() {
    }

    @Around("anyMethod()")
    public Object lockAndUnlock(ProceedingJoinPoint joinPoint) throws Throwable {
        Object object = joinPoint.proceed();
        return object;
    }
}
public static void main(String[] args) {
    boolean b = new NativeDiscovery().discover();

    if (b) {
        springContext = new AnnotationConfigApplicationContext(PlayerBeanConfig.class);

        String[] kkk = new String[]{};
        TestMediaList list = springContext.
                getBean(TestMediaList.class, LibVlc.INSTANCE, LibVlc.INSTANCE.libvlc_new(kkk.length, kkk));

        System.out.println(list.mediaListInstance()); // <- proxy object return null
    } else {
        logger.error("Cannot find vlc lib, exit application");
    }
}
public class TargetClass {
    private String returnValue;

    public TargetClass() {
        this.returnValue = "Hello World";
    }

    public final String test() {
        System.out.println("TargetClass.test();");
        return returnValue;
    }
}
@Aspect
public class AspectClass {
    @Pointcut("execution(* vod.demo.TargetClass.*(..))")
    private void targetMethod() {
    }

    @Around("targetMethod()")
    public Object aroundTarget(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("AspectClass.aroundTarget();");
        return joinPoint.proceed();
    }
}
@Configuration
@EnableAspectJAutoProxy
@Import(AspectClass.class)
public class SpringConfig {
    @Bean
    public TargetClass target() {
        return new TargetClass();
    }
}
public class Client {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        TargetClass target = context.getBean(TargetClass.class);
        System.out.println("Client invoke:" + target.test()); // <- output null
    }
}
public final libvlc_media_list_t mediaListInstance() {
    return mediaListInstance; // <- proxy object return null, if use aop
}
public final String test() {
    System.out.println("TargetClass.test();");
    return returnValue;
}
22:35:31.773 [main] INFO  o.s.aop.framework.CglibAopProxy - Unable to proxy method [public final java.lang.String com.example.root.TargetClass.test()] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
public final String test() {
    System.out.println("TargetClass.test();");
    return returnValue;
}