/*
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.jmx.support;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jmx.MBeanServerNotFoundException;
import org.springframework.lang.Nullable;
FactoryBean
that obtains a MBeanServer
reference through the standard JMX 1.2 MBeanServerFactory
API. Exposes the MBeanServer
for bean references.
By default, MBeanServerFactoryBean
will always create a new MBeanServer
even if one is already running. To have the MBeanServerFactoryBean
attempt to locate a running MBeanServer
first, set the value of the "locateExistingServerIfPossible" property to "true".
Author: Rob Harrop, Juergen Hoeller See Also: Since: 1.2
/**
* {@link FactoryBean} that obtains a {@link javax.management.MBeanServer} reference
* through the standard JMX 1.2 {@link javax.management.MBeanServerFactory}
* API.
*
* <p>Exposes the {@code MBeanServer} for bean references.
*
* <p>By default, {@code MBeanServerFactoryBean} will always create
* a new {@code MBeanServer} even if one is already running. To have
* the {@code MBeanServerFactoryBean} attempt to locate a running
* {@code MBeanServer} first, set the value of the
* "locateExistingServerIfPossible" property to "true".
*
* @author Rob Harrop
* @author Juergen Hoeller
* @since 1.2
* @see #setLocateExistingServerIfPossible
* @see #locateMBeanServer
* @see javax.management.MBeanServer
* @see javax.management.MBeanServerFactory#findMBeanServer
* @see javax.management.MBeanServerFactory#createMBeanServer
* @see javax.management.MBeanServerFactory#newMBeanServer
* @see MBeanServerConnectionFactoryBean
* @see ConnectorServerFactoryBean
*/
public class MBeanServerFactoryBean implements FactoryBean<MBeanServer>, InitializingBean, DisposableBean {
protected final Log logger = LogFactory.getLog(getClass());
private boolean locateExistingServerIfPossible = false;
@Nullable
private String agentId;
@Nullable
private String defaultDomain;
private boolean registerWithFactory = true;
@Nullable
private MBeanServer server;
private boolean newlyRegistered = false;
Set whether or not the MBeanServerFactoryBean
should attempt to locate a running MBeanServer
before creating one. Default is false
.
/**
* Set whether or not the {@code MBeanServerFactoryBean} should attempt
* to locate a running {@code MBeanServer} before creating one.
* <p>Default is {@code false}.
*/
public void setLocateExistingServerIfPossible(boolean locateExistingServerIfPossible) {
this.locateExistingServerIfPossible = locateExistingServerIfPossible;
}
Set the agent id of the MBeanServer
to locate. Default is none. If specified, this will result in an
automatic attempt being made to locate the attendant MBeanServer,
and (importantly) if said MBeanServer cannot be located no
attempt will be made to create a new MBeanServer (and an
MBeanServerNotFoundException will be thrown at resolution time).
Specifying the empty String indicates the platform MBeanServer.
See Also:
/**
* Set the agent id of the {@code MBeanServer} to locate.
* <p>Default is none. If specified, this will result in an
* automatic attempt being made to locate the attendant MBeanServer,
* and (importantly) if said MBeanServer cannot be located no
* attempt will be made to create a new MBeanServer (and an
* MBeanServerNotFoundException will be thrown at resolution time).
* <p>Specifying the empty String indicates the platform MBeanServer.
* @see javax.management.MBeanServerFactory#findMBeanServer(String)
*/
public void setAgentId(String agentId) {
this.agentId = agentId;
}
Set the default domain to be used by the MBeanServer
, to be passed to MBeanServerFactory.createMBeanServer()
or MBeanServerFactory.findMBeanServer()
. Default is none.
See Also:
/**
* Set the default domain to be used by the {@code MBeanServer},
* to be passed to {@code MBeanServerFactory.createMBeanServer()}
* or {@code MBeanServerFactory.findMBeanServer()}.
* <p>Default is none.
* @see javax.management.MBeanServerFactory#createMBeanServer(String)
* @see javax.management.MBeanServerFactory#findMBeanServer(String)
*/
public void setDefaultDomain(String defaultDomain) {
this.defaultDomain = defaultDomain;
}
Set whether to register the MBeanServer
with the MBeanServerFactory
, making it available through MBeanServerFactory.findMBeanServer()
. Default is true
.
See Also:
/**
* Set whether to register the {@code MBeanServer} with the
* {@code MBeanServerFactory}, making it available through
* {@code MBeanServerFactory.findMBeanServer()}.
* <p>Default is {@code true}.
* @see javax.management.MBeanServerFactory#createMBeanServer
* @see javax.management.MBeanServerFactory#findMBeanServer
*/
public void setRegisterWithFactory(boolean registerWithFactory) {
this.registerWithFactory = registerWithFactory;
}
Creates the MBeanServer
instance. /**
* Creates the {@code MBeanServer} instance.
*/
@Override
public void afterPropertiesSet() throws MBeanServerNotFoundException {
// Try to locate existing MBeanServer, if desired.
if (this.locateExistingServerIfPossible || this.agentId != null) {
try {
this.server = locateMBeanServer(this.agentId);
}
catch (MBeanServerNotFoundException ex) {
// If agentId was specified, we were only supposed to locate that
// specific MBeanServer; so let's bail if we can't find it.
if (this.agentId != null) {
throw ex;
}
logger.debug("No existing MBeanServer found - creating new one");
}
}
// Create a new MBeanServer and register it, if desired.
if (this.server == null) {
this.server = createMBeanServer(this.defaultDomain, this.registerWithFactory);
this.newlyRegistered = this.registerWithFactory;
}
}
Attempt to locate an existing MBeanServer
. Called if locateExistingServerIfPossible
is set to true
. The default implementation attempts to find an MBeanServer
using a standard lookup. Subclasses may override to add additional location logic.
Params: - agentId – the agent identifier of the MBeanServer to retrieve. If this parameter is
null
, all registered MBeanServers are considered.
Throws: - MBeanServerNotFoundException – if no
MBeanServer
could be found
See Also: Returns: the MBeanServer
if found
/**
* Attempt to locate an existing {@code MBeanServer}.
* Called if {@code locateExistingServerIfPossible} is set to {@code true}.
* <p>The default implementation attempts to find an {@code MBeanServer} using
* a standard lookup. Subclasses may override to add additional location logic.
* @param agentId the agent identifier of the MBeanServer to retrieve.
* If this parameter is {@code null}, all registered MBeanServers are
* considered.
* @return the {@code MBeanServer} if found
* @throws org.springframework.jmx.MBeanServerNotFoundException
* if no {@code MBeanServer} could be found
* @see #setLocateExistingServerIfPossible
* @see JmxUtils#locateMBeanServer(String)
* @see javax.management.MBeanServerFactory#findMBeanServer(String)
*/
protected MBeanServer locateMBeanServer(@Nullable String agentId) throws MBeanServerNotFoundException {
return JmxUtils.locateMBeanServer(agentId);
}
Create a new MBeanServer
instance and register it with the MBeanServerFactory
, if desired. Params: - defaultDomain – the default domain, or
null
if none - registerWithFactory – whether to register the
MBeanServer
with the MBeanServerFactory
See Also:
/**
* Create a new {@code MBeanServer} instance and register it with the
* {@code MBeanServerFactory}, if desired.
* @param defaultDomain the default domain, or {@code null} if none
* @param registerWithFactory whether to register the {@code MBeanServer}
* with the {@code MBeanServerFactory}
* @see javax.management.MBeanServerFactory#createMBeanServer
* @see javax.management.MBeanServerFactory#newMBeanServer
*/
protected MBeanServer createMBeanServer(@Nullable String defaultDomain, boolean registerWithFactory) {
if (registerWithFactory) {
return MBeanServerFactory.createMBeanServer(defaultDomain);
}
else {
return MBeanServerFactory.newMBeanServer(defaultDomain);
}
}
@Override
@Nullable
public MBeanServer getObject() {
return this.server;
}
@Override
public Class<? extends MBeanServer> getObjectType() {
return (this.server != null ? this.server.getClass() : MBeanServer.class);
}
@Override
public boolean isSingleton() {
return true;
}
Unregisters the MBeanServer
instance, if necessary. /**
* Unregisters the {@code MBeanServer} instance, if necessary.
*/
@Override
public void destroy() {
if (this.newlyRegistered) {
MBeanServerFactory.releaseMBeanServer(this.server);
}
}
}