gpt4 book ai didi

java - 导出延迟初始化的 bean(实现 SelfNaming 并使用 ManagedResource 注释进行注释)会给出 IllegalStateException

转载 作者:行者123 更新时间:2023-11-30 01:58:10 25 4
gpt4 key购买 nike

我有一颗 bean

  • 使用 ManagedResource 进行注释
  • 延迟初始化
  • 实现SelfNaming

我使用 spring 的 AnnotationMBeanExporter 导出它。

当我使用 spring 版本 4.3.16.RELEASE 时,所有这些都运行良好,但是当我将 spring 版本升级到 5.0.5.RELEASE5.1.3.RELEASE这段代码开始给我IllegalStateException

我的 Bean 定义和 spring 的 context.xml 如下所示:

SampleBean.java:

package com.jmx.trial.dummybeans;

import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.jmx.export.naming.SelfNaming;

import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;

@ManagedResource
public class SampleBean implements SelfNaming {
@Override
public ObjectName getObjectName() throws MalformedObjectNameException {
return new ObjectName("com.jmx.trial:name=sampleBean");
}
}

应用程序上下文.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="server" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>

<bean id="exporter" class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter">
<property name="server" ref="server"/>
</bean>

<bean id="sampleBean" class="com.jmx.trial.dummybeans.SampleBean" lazy-init="true"/>

</beans>

据我所知,添加了额外的验证 here ,这导致了 IllegalStateException 但我不完全确定为什么要添加它。

堆栈跟踪如下所示:

org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [sampleBean] with key 'sampleBean'; nested exception is java.lang.IllegalStateException: Not initialized

at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:625)
at org.springframework.jmx.export.MBeanExporter.lambda$registerBeans$2(MBeanExporter.java:551)
at java.base/java.util.HashMap.forEach(HashMap.java:1336)
at org.springframework.jmx.export.MBeanExporter.registerBeans(MBeanExporter.java:551)
at org.springframework.jmx.export.MBeanExporter.afterSingletonsInstantiated(MBeanExporter.java:434)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:863)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
at com.jmx.trial.MBeanExporterTest.testBeanExportedWithXml(MBeanExporterTest.java:79)
at com.jmx.trial.MBeanExporterTest.testForLazyAutoDetectWithSelfNaming(MBeanExporterTest.java:44)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalStateException: Not initialized
at org.springframework.util.Assert.state(Assert.java:73)
at org.springframework.jmx.export.MBeanExporter$NotificationPublisherAwareLazyTargetSource.postProcessTargetObject(MBeanExporter.java:1115)
at org.springframework.aop.target.LazyInitTargetSource.getTarget(LazyInitTargetSource.java:72)
at org.springframework.jmx.export.MBeanExporter$NotificationPublisherAwareLazyTargetSource.getTarget(MBeanExporter.java:1103)
at org.springframework.aop.framework.CglibAopProxy$DynamicUnadvisedInterceptor.intercept(CglibAopProxy.java:475)
at com.jmx.trial.dummybeans.SampleBean$$EnhancerBySpringCGLIB$$9cd1c95b.getObjectName(<generated>)
at org.springframework.jmx.export.MBeanExporter.getObjectName(MBeanExporter.java:752)
at org.springframework.jmx.export.MBeanExporter.registerLazyInit(MBeanExporter.java:726)
at org.springframework.jmx.export.MBeanExporter.registerBeanNameOrInstance(MBeanExporter.java:596)
... 33 more

我的实验:

  • 当我不延迟初始化 sampleBean 时,我不会收到此 IllegalStateException
  • 当我使用 ManagedResource(objectName = "com.jmx.trial:name=sampleBean") 注释 SampleBean 并让 SampleBean 实现时, SelfNaming 接口(interface),我再次没有得到 IllegalStateException

虽然不太确定,但我认为实现 SelfNaming 接口(interface)并不是一个好主意,因为 SelfNaming 接口(interface)的 javadoc 说:

This interface is mainly intended for internal usage.

我不确定这是否是使用SelfNaming接口(interface)的问题,或者我正在做一些根本错误的事情。您能否解释一下这种行为并指出我所缺少的基本原理。

PS:我的一些发现:(可能不相关)来自 here我发现了这个警告点:

Do not use interface-based AOP proxies in combination with autodetection of JMX annotations in your bean classes.

我不太明白这一点,但这是否是我违反的规则?

最佳答案

这可能是一个错误; injectNotificationPublisherIfNecessary 仅当您的类也实现 NotificationPublisherAware 时才执行任何操作。

这将是无效的,因为我们还没有 objectName,因为 Bean 是惰性的,这会违反 ModelMBeanNotificationPublisher 的约定。

如果资源没有实现发布者感知接口(interface),我不知道 postProcessTargetObject 是否可以忽略断言,或者发布者注入(inject)是否也需要延迟进行。我不太了解内部原理。

我建议您打开SPR JIRA issue这样 Spring 团队可以查看并给您一个明确的答案。

关于java - 导出延迟初始化的 bean(实现 SelfNaming 并使用 ManagedResource 注释进行注释)会给出 IllegalStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53711613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com