Java Spring AOP CGLIB代理';s字段为空 描述
使用该组件时,自定义组件将显示为AOP代理对象null的结果 媒体列表类 Spring配置类 AOP配置类 测试代码 方面类 Spring配置类 客户端类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
公共类客户端{
公共静态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;
}