Spring JMX 注入的一些問題和說明


項目中使用Spring JMX來直接把Bean 暴露成MBean,發現用<context:mbean-export />簡潔標籤會一直報Jndi的錯誤,初步猜測是從遠端查找。

首先,看了http://www.springframework.org/schema/context/spring-context-3.1.xsd

其中一段:

<xsd:attribute name="server" type="xsd:string">
<xsd:annotation><xsd:documentation>
<![CDATA[The bean name of the MBeanServer to which MBeans should be exported. Default is to use the platform's default MBeanServer (autodetecting WebLogic 9+, WebSphere 5.1+ and the JDK 1.5+ platform MBeanServer).]]>
</xsd:documentation></xsd:annotation></xsd:attribute>


對容器做了特殊處理。

查看標籤對應的解析類MBeanServerBeanDefinitionParser.java,果然如此。

	private static final boolean weblogicPresent = ClassUtils.isPresent(
			"weblogic.management.Helper", MBeanServerBeanDefinitionParser.class.getClassLoader());


	private static final boolean webspherePresent = ClassUtils.isPresent(
			"com.ibm.websphere.management.AdminServiceFactory", MBeanServerBeanDefinitionParser.class.getClassLoader());

static AbstractBeanDefinition findServerForSpecialEnvironment() {
		if (weblogicPresent) {
			RootBeanDefinition bd = new RootBeanDefinition(JndiObjectFactoryBean.class);
			bd.getPropertyValues().add("jndiName", "java:comp/env/jmx/runtime");
			return bd;
		}
		else if (webspherePresent) {
			return new RootBeanDefinition(WebSphereMBeanServerFactoryBean.class);
		}
		else {
			return null;
		}
	}



MBeanExportBeanDefinitionParser.java

	        if (StringUtils.hasText(serverBeanName)) {
			builder.addPropertyReference("server", serverBeanName);
		}
		else {
			AbstractBeanDefinition specialServer = MBeanServerBeanDefinitionParser.findServerForSpecialEnvironment();
			if (specialServer != null) {
				builder.addPropertyValue("server", specialServer);
			}
		}


		String registration = element.getAttribute(REGISTRATION_ATTRIBUTE);
		int registrationBehavior = MBeanRegistrationSupport.REGISTRATION_FAIL_ON_EXISTING;
		if (REGISTRATION_IGNORE_EXISTING.equals(registration)) {
			registrationBehavior = MBeanRegistrationSupport.REGISTRATION_IGNORE_EXISTING;
		}
		else if (REGISTRATION_REPLACE_EXISTING.equals(registration)) {
			registrationBehavior = MBeanRegistrationSupport.REGISTRATION_REPLACE_EXISTING;
		}
		builder.addPropertyValue("registrationBehavior", registrationBehavior);


		return builder.getBeanDefinition();



MBeanServerBeanDefinitionParser.java

		AbstractBeanDefinition specialServer = findServerForSpecialEnvironment();
		if (specialServer != null) {
			return specialServer;
		}
		RootBeanDefinition bd = new RootBeanDefinition(MBeanServerFactoryBean.class);
		bd.getPropertyValues().add("locateExistingServerIfPossible", Boolean.TRUE);


		// Mark as infrastructure bean and attach source location.
		bd.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		bd.setSource(parserContext.extractSource(element));
		return bd;



因爲項目中使用了weblogic,所以classpath中包含weblogic.jar,索性去掉後,jmx server正常了。

另外如果自定義mbeanServer,locateExistingServerIfPossible要設置爲true,否則自定義的mbean不會出現。

<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"
		lazy-init="false">
		<property name="locateExistingServerIfPossible" value="true" />
	......
	</bean>





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章