001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.jmx.support;
018:
019: import javax.management.MBeanServer;
020: import javax.management.MBeanServerFactory;
021:
022: import org.apache.commons.logging.Log;
023: import org.apache.commons.logging.LogFactory;
024:
025: import org.springframework.beans.factory.DisposableBean;
026: import org.springframework.beans.factory.FactoryBean;
027: import org.springframework.beans.factory.InitializingBean;
028: import org.springframework.jmx.MBeanServerNotFoundException;
029:
030: /**
031: * FactoryBean that obtains an {@link javax.management.MBeanServer} reference
032: * through the standard JMX 1.2 {@link javax.management.MBeanServerFactory}
033: * API (which is available on JDK 1.5 or as part of a JMX 1.2 provider).
034: * Exposes the <code>MBeanServer</code> for bean references.
035: *
036: * <p>By default, <code>MBeanServerFactoryBean</code> will always create
037: * a new <code>MBeanServer</code> even if one is already running. To have
038: * the <code>MBeanServerFactoryBean</code> attempt to locate a running
039: * <code>MBeanServer</code> first, set the value of the
040: * "locateExistingServerIfPossible" property to "true".
041: *
042: * @author Rob Harrop
043: * @author Juergen Hoeller
044: * @since 1.2
045: * @see #setLocateExistingServerIfPossible
046: * @see #locateMBeanServer
047: * @see javax.management.MBeanServer
048: * @see javax.management.MBeanServerFactory#findMBeanServer
049: * @see javax.management.MBeanServerFactory#createMBeanServer
050: * @see javax.management.MBeanServerFactory#newMBeanServer
051: * @see MBeanServerConnectionFactoryBean
052: * @see ConnectorServerFactoryBean
053: */
054: public class MBeanServerFactoryBean implements FactoryBean,
055: InitializingBean, DisposableBean {
056:
057: protected final Log logger = LogFactory.getLog(getClass());
058:
059: private boolean locateExistingServerIfPossible = false;
060:
061: private String agentId;
062:
063: private String defaultDomain;
064:
065: private boolean registerWithFactory = true;
066:
067: private MBeanServer server;
068:
069: private boolean newlyRegistered = false;
070:
071: /**
072: * Set whether or not the <code>MBeanServerFactoryBean</code> should attempt
073: * to locate a running <code>MBeanServer</code> before creating one.
074: * <p>Default is <code>false</code>.
075: */
076: public void setLocateExistingServerIfPossible(
077: boolean locateExistingServerIfPossible) {
078: this .locateExistingServerIfPossible = locateExistingServerIfPossible;
079: }
080:
081: /**
082: * Set the agent id of the <code>MBeanServer</code> to locate.
083: * <p>Default is none. If specified, this will result in an
084: * automatic attempt being made to locate the attendant MBeanServer,
085: * and (importantly) if said MBeanServer cannot be located no
086: * attempt will be made to create a new MBeanServer (and an
087: * MBeanServerNotFoundException will be thrown at resolution time).
088: * @see javax.management.MBeanServerFactory#findMBeanServer(String)
089: */
090: public void setAgentId(String agentId) {
091: this .agentId = agentId;
092: }
093:
094: /**
095: * Set the default domain to be used by the <code>MBeanServer</code>,
096: * to be passed to <code>MBeanServerFactory.createMBeanServer()</code>
097: * or <code>MBeanServerFactory.findMBeanServer()<code>.
098: * <p>Default is none.
099: * @see javax.management.MBeanServerFactory#createMBeanServer(String)
100: * @see javax.management.MBeanServerFactory#findMBeanServer(String)
101: */
102: public void setDefaultDomain(String defaultDomain) {
103: this .defaultDomain = defaultDomain;
104: }
105:
106: /**
107: * Set whether to register the <code>MBeanServer</code> with the
108: * <code>MBeanServerFactory</code>, making it available through
109: * <code>MBeanServerFactory.findMBeanServer()<code>.
110: * @see javax.management.MBeanServerFactory#createMBeanServer
111: * @see javax.management.MBeanServerFactory#findMBeanServer
112: */
113: public void setRegisterWithFactory(boolean registerWithFactory) {
114: this .registerWithFactory = registerWithFactory;
115: }
116:
117: /**
118: * Creates the <code>MBeanServer</code> instance.
119: */
120: public void afterPropertiesSet()
121: throws MBeanServerNotFoundException {
122: // Try to locate existing MBeanServer, if desired.
123: if (this .locateExistingServerIfPossible || this .agentId != null) {
124: try {
125: this .server = locateMBeanServer(this .agentId);
126: } catch (MBeanServerNotFoundException ex) {
127: // If agentId was specified, we were only supposed to locate that
128: // specific MBeanServer; so let's bail if we can't find it.
129: if (this .agentId != null) {
130: throw ex;
131: }
132: logger
133: .info("No existing MBeanServer found - creating new one");
134: }
135: }
136:
137: // Create a new MBeanServer and register it, if desired.
138: if (this .server == null) {
139: this .server = createMBeanServer(this .defaultDomain,
140: this .registerWithFactory);
141: this .newlyRegistered = this .registerWithFactory;
142: }
143: }
144:
145: /**
146: * Attempt to locate an existing <code>MBeanServer</code>.
147: * Called if <code>locateExistingServerIfPossible</code> is set to <code>true</code>.
148: * <p>The default implementation attempts to find an <code>MBeanServer</code> using
149: * a standard lookup. Subclasses may override to add additional location logic.
150: * @param agentId the agent identifier of the MBeanServer to retrieve.
151: * If this parameter is <code>null</code>, all registered MBeanServers are
152: * considered.
153: * @return the <code>MBeanServer</code> if found
154: * @throws org.springframework.jmx.MBeanServerNotFoundException
155: * if no <code>MBeanServer</code> could be found
156: * @see #setLocateExistingServerIfPossible
157: * @see JmxUtils#locateMBeanServer(String)
158: * @see javax.management.MBeanServerFactory#findMBeanServer(String)
159: */
160: protected MBeanServer locateMBeanServer(String agentId)
161: throws MBeanServerNotFoundException {
162: return JmxUtils.locateMBeanServer(agentId);
163: }
164:
165: /**
166: * Create a new <code>MBeanServer</code> instance and register it with the
167: * <code>MBeanServerFactory</code>, if desired.
168: * @param defaultDomain the default domain, or <code>null</code> if none
169: * @param registerWithFactory whether to register the <code>MBeanServer</code>
170: * with the <code>MBeanServerFactory</code>
171: * @see javax.management.MBeanServerFactory#createMBeanServer
172: * @see javax.management.MBeanServerFactory#newMBeanServer
173: */
174: protected MBeanServer createMBeanServer(String defaultDomain,
175: boolean registerWithFactory) {
176: if (registerWithFactory) {
177: return MBeanServerFactory.createMBeanServer(defaultDomain);
178: } else {
179: return MBeanServerFactory.newMBeanServer(defaultDomain);
180: }
181: }
182:
183: public Object getObject() {
184: return this .server;
185: }
186:
187: public Class getObjectType() {
188: return (this .server != null ? this .server.getClass()
189: : MBeanServer.class);
190: }
191:
192: public boolean isSingleton() {
193: return true;
194: }
195:
196: /**
197: * Unregisters the <code>MBeanServer</code> instance, if necessary.
198: */
199: public void destroy() {
200: if (this.newlyRegistered) {
201: MBeanServerFactory.releaseMBeanServer(this.server);
202: }
203: }
204:
205: }
|