当前位置: 首页 > 知识库问答 >
问题:

@预拉伸和SpringAOP兼容性

易成天
2023-03-14

我想在优雅的关闭上做一些工作。
我尝试了如下所示的方法,但它不起作用。
我找到了一个解决方法(在ContextClosedEvent的@EventListener标记方法上放置方面注释),但我想了解它失败的原因(Aud()方法没有任何异常根本没有调用)。

@SpringBootApplication
public class Application {

    public static void main(String args[]) {
       SpringApplication.run(Application.class, args);
    }
    
    @AuditProcess
    @PreDestroy
    public void destroy() {
    }
}
@Aspect
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class AuditProcessAspect {

    @Pointcut("@annotation(com.aaa.bbb.annotation.AuditProcess) && execution(public * *(..))")
    public void executionOfPublicAuditableMethod() {
    }

    @Around("executionOfPublicAuditableMethod()")
    public Object audit(ProceedingJoinPoint joinPoint) {
        // some business logic ...
    }
}

就我对Spring 5的研究而言,我发现@PreDestroy由CommonAnnotationBeanPostProcessor处理,而@Aspect类由AspectJAdvisorFactory(我猜是JDK代理上的CGLIB)转换为Spring AOP顾问。因此,我不明白为什么在将SIGTERM发送到应用程序的JVM进程后不调用方面逻辑。我甚至检查了<code>System.out.println(this.getClass())的输出。getCanonicalName()),它被放在<code>destroy()方法的主体中-例如,它看起来像是应用程序$$EnhancerBySpringCGLIB$$25f99bf7。从我目前的观点来看,没有什么可以阻止方面围绕@PreDestroy回调方法包装<然而,它不起作用<有人能解释一下原因吗?

共有2个答案

戚默
2023-03-14

以下是我的分析<修改了code>main()方法以说明bean方法触发器。

@SpringBootApplication
public class MainApp {
    
    public static void main(String[] args) {
        ConfigurableApplicationContext context = new SpringApplication(MainApp.class).run(args);
        MainApp app = context.getBean(MainApp.class);
        app.destroy();
    }


    @PreDestroy
    @AuditProcess
    public void destroy() {
        System.out.println("PreDestroy");
    }
}

当在 main() 方法中调用 app.destory() 时,调用在代理上完成

MainApp$$EnhancerBySpringCGLIB$$f2c7a1b4(MainApp).destroy() line: 25    
MainApp$$FastClassBySpringCGLIB$$8fbee297.invoke(int, Object, Object[]) line: not available 
MethodProxy.invoke(Object, Object[]) line: 218  
... 
MyAspect.preDestroyLog(ProceedingJoinPoint) line: 27    
... 
CglibAopProxy$DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy) line: 692  
MainApp$$EnhancerBySpringCGLIB$$b98f9ed6.destroy() line: not available  
MainApp.main(String[]) line: 18 

当Application ationContext关闭时,生命周期回调是由实际对象而不是代理上的InitDestRoyAnNotationBeanPostProcencer$LifecycleMetadata.invokeDestroyMethods(Object, String)完成的,因此不会发生任何建议。

MainApp$$EnhancerBySpringCGLIB$$f2c7a1b4(MainApp).destroy() line: 25    
NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method]  
NativeMethodAccessorImpl.invoke(Object, Object[]) line: 62  
DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 43  
Method.invoke(Object, Object...) line: 566  
InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(Object) line: 389    
InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeDestroyMethods(Object, String) line: 347 
CommonAnnotationBeanPostProcessor(InitDestroyAnnotationBeanPostProcessor).postProcessBeforeDestruction(Object, String) line: 177    
DisposableBeanAdapter.destroy() line: 242   
DefaultListableBeanFactory(DefaultSingletonBeanRegistry).destroyBean(String, DisposableBean) line: 587  
DefaultListableBeanFactory(DefaultSingletonBeanRegistry).destroySingleton(String) line: 559 
DefaultListableBeanFactory.destroySingleton(String) line: 1152  
DefaultListableBeanFactory(DefaultSingletonBeanRegistry).destroySingletons() line: 520  
DefaultListableBeanFactory.destroySingletons() line: 1145   
AnnotationConfigApplicationContext(AbstractApplicationContext).destroyBeans() line: 1111    
AnnotationConfigApplicationContext(AbstractApplicationContext).doClose() line: 1080 
AbstractApplicationContext$1.run() line: 996
海鸣
2023-03-14

如果您像 appContext.getBean(Application.class).destroy() 那样手动调用 pre-destroy 方法,则会触发该方面。但是,在应用程序被销毁的生命周期部分,似乎不再应用任何方面。

根据javadoc@PreDestroy,带注释的目标方法可能是私有的,甚至是最终的,即两个特征与基于代理的Spring AOP用法相矛盾。我根本不是Spring或Java EE用户,我可能是错的,但对我来说,这似乎不应该按照你期望的方式工作。像M. Deinum或R.G这样的Spring专家也许能够更多地了解这个问题。

 类似资料:
  • 我一直在努力在Android上制作我的自定义相机活动,但当旋转相机时,表面视图的纵横比会变得混乱。 在我的oncreate for the activity中,我设置了framelayout,它保存了显示相机参数的曲面视图。 然后,在曲面视图中,我设置要显示的相机参数 您可以看到,当手机旋转时,乐高男会变得更高、更瘦: 如何确保相机视图的纵横比正确?

  • 本文向大家介绍拉伸相关面试题,主要包含被问及拉伸时的应答技巧和注意事项,需要的朋友参考一下 “ a”标签是内联级别元素。没有内联级别元素可以设置其宽度。为什么?因为内联级别的元素是要表示流畅的文本的,所以理论上可以从一行换行到另一行。在这种情况下,提供元素的宽度是没有意义的,因为您不一定知道它是否要包装。为了设置其宽度,您必须将其显示属性更改为或: 如果有内存,则 可以 在IE6中的某些内联级别元

  • 如何使页面更大,使文本/图像根据新的大小进行拉伸?我只找到了缩小但不扩大的方法。。。有什么想法吗? 提前感谢!!!

  • 本文向大家介绍javascript图片预览和上传(兼容IE),包括了javascript图片预览和上传(兼容IE)的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了js图片预览和上传的具体代码,供大家参考,具体内容如下 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 问题内容: 我需要伸展黄色的孩子来填补父母的所有身高。无需设置父级高度。父级的高度应取决于蓝色的子级文本。 问题答案: 使用Flexbox时,主要错误是开始全面使用。 在很多情况下,我们已经习惯了这一点,尽管谈到Flexbox时,它通常会破坏它。 解决方案很简单,只需删除,它将自动运行。 它的原因,是 柔性的项目 在 行 方向(默认),控制垂直行为,并作为其默认的是这只是工作原样。 堆栈片段

  • 问题内容: 有没有一种方法可以使CSS背景拉伸或缩放以填充其容器? 问题答案: 对于现代浏览器,您可以使用以下命令完成此操作: 表示垂直或水平拉伸图像,因此它永远不会平铺/重复。 适用于Safari3(或更高版本),Chrome,Opera10 +,Firefox 3.6+和Internet Explorer 9(或更高版本)。 要使其与较低版本的Internet Explorer一起使用,请尝试