• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TAKETODAY / today-infrastructure / 18275228018

06 Oct 2025 08:46AM UTC coverage: 82.371% (+0.3%) from 82.116%
18275228018

push

github

TAKETODAY
:white_check_mark:

60099 of 78037 branches covered (77.01%)

Branch coverage included in aggregate %.

142159 of 167507 relevant lines covered (84.87%)

3.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.76
today-context/src/main/java/infra/jmx/support/MBeanServerConnectionFactoryBean.java
1
/*
2
 * Copyright 2017 - 2025 the original author or authors.
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see [https://www.gnu.org/licenses/]
16
 */
17

18
package infra.jmx.support;
19

20
import org.jspecify.annotations.Nullable;
21

22
import java.io.IOException;
23
import java.net.MalformedURLException;
24
import java.util.HashMap;
25
import java.util.Map;
26
import java.util.Properties;
27

28
import javax.management.MBeanServerConnection;
29
import javax.management.remote.JMXConnector;
30
import javax.management.remote.JMXConnectorFactory;
31
import javax.management.remote.JMXServiceURL;
32

33
import infra.aop.TargetSource;
34
import infra.aop.framework.ProxyFactory;
35
import infra.aop.target.AbstractLazyCreationTargetSource;
36
import infra.beans.factory.BeanClassLoaderAware;
37
import infra.beans.factory.DisposableBean;
38
import infra.beans.factory.FactoryBean;
39
import infra.beans.factory.InitializingBean;
40
import infra.jmx.access.MBeanClientInterceptor;
41
import infra.jmx.access.NotificationListenerRegistrar;
42
import infra.lang.Assert;
43
import infra.util.ClassUtils;
44
import infra.util.CollectionUtils;
45

46
/**
47
 * {@link FactoryBean} that creates a JMX 1.2 {@code MBeanServerConnection}
48
 * to a remote {@code MBeanServer} exposed via a {@code JMXServerConnector}.
49
 * Exposes the {@code MBeanServer} for bean references.
50
 *
51
 * @author Rob Harrop
52
 * @author Juergen Hoeller
53
 * @author <a href="https://github.com/TAKETODAY">海子 Yang</a>
54
 * @see MBeanServerFactoryBean
55
 * @see ConnectorServerFactoryBean
56
 * @see MBeanClientInterceptor#setServer
57
 * @see NotificationListenerRegistrar#setServer
58
 * @since 4.0
59
 */
60
public class MBeanServerConnectionFactoryBean
2✔
61
        implements FactoryBean<MBeanServerConnection>, BeanClassLoaderAware, InitializingBean, DisposableBean {
62

63
  @Nullable
64
  private JMXServiceURL serviceUrl;
65

66
  private final Map<String, Object> environment = new HashMap<>();
5✔
67

68
  private boolean connectOnStartup = true;
3✔
69

70
  @Nullable
2✔
71
  private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
2✔
72

73
  @Nullable
74
  private JMXConnector connector;
75

76
  @Nullable
77
  private MBeanServerConnection connection;
78

79
  @Nullable
80
  private JMXConnectorLazyInitTargetSource connectorTargetSource;
81

82
  /**
83
   * Set the service URL of the remote {@code MBeanServer}.
84
   */
85
  public void setServiceUrl(String url) throws MalformedURLException {
86
    this.serviceUrl = new JMXServiceURL(url);
6✔
87
  }
1✔
88

89
  /**
90
   * Set the environment properties used to construct the {@code JMXConnector}
91
   * as {@code java.util.Properties} (String key/value pairs).
92
   */
93
  public void setEnvironment(Properties environment) {
94
    CollectionUtils.mergePropertiesIntoMap(environment, this.environment);
×
95
  }
×
96

97
  /**
98
   * Set the environment properties used to construct the {@code JMXConnector}
99
   * as a {@code Map} of String keys and arbitrary Object values.
100
   */
101
  public void setEnvironmentMap(@Nullable Map<String, ?> environment) {
102
    if (environment != null) {
×
103
      this.environment.putAll(environment);
×
104
    }
105
  }
×
106

107
  /**
108
   * Set whether to connect to the server on startup.
109
   * <p>Default is {@code true}.
110
   * <p>Can be turned off to allow for late start of the JMX server.
111
   * In this case, the JMX connector will be fetched on first access.
112
   */
113
  public void setConnectOnStartup(boolean connectOnStartup) {
114
    this.connectOnStartup = connectOnStartup;
3✔
115
  }
1✔
116

117
  @Override
118
  public void setBeanClassLoader(ClassLoader classLoader) {
119
    this.beanClassLoader = classLoader;
×
120
  }
×
121

122
  /**
123
   * Creates a {@code JMXConnector} for the given settings
124
   * and exposes the associated {@code MBeanServerConnection}.
125
   */
126
  @Override
127
  public void afterPropertiesSet() throws IOException {
128
    if (this.serviceUrl == null) {
3✔
129
      throw new IllegalArgumentException("Property 'serviceUrl' is required");
5✔
130
    }
131

132
    if (this.connectOnStartup) {
3✔
133
      connect();
3✔
134
    }
135
    else {
136
      createLazyConnection();
2✔
137
    }
138
  }
1✔
139

140
  /**
141
   * Connects to the remote {@code MBeanServer} using the configured service URL and
142
   * environment properties.
143
   */
144
  private void connect() throws IOException {
145
    Assert.state(this.serviceUrl != null, "No JMXServiceURL set");
7!
146
    this.connector = JMXConnectorFactory.connect(this.serviceUrl, this.environment);
7✔
147
    this.connection = this.connector.getMBeanServerConnection();
5✔
148
  }
1✔
149

150
  /**
151
   * Creates lazy proxies for the {@code JMXConnector} and {@code MBeanServerConnection}.
152
   */
153
  private void createLazyConnection() {
154
    this.connectorTargetSource = new JMXConnectorLazyInitTargetSource();
6✔
155
    TargetSource connectionTargetSource = new MBeanServerConnectionLazyInitTargetSource();
5✔
156

157
    this.connector = (JMXConnector)
9✔
158
            new ProxyFactory(JMXConnector.class, this.connectorTargetSource).getProxy(this.beanClassLoader);
3✔
159
    this.connection = (MBeanServerConnection)
8✔
160
            new ProxyFactory(MBeanServerConnection.class, connectionTargetSource).getProxy(this.beanClassLoader);
3✔
161
  }
1✔
162

163
  @Override
164
  @Nullable
165
  public MBeanServerConnection getObject() {
166
    return this.connection;
3✔
167
  }
168

169
  @Override
170
  public Class<? extends MBeanServerConnection> getObjectType() {
171
    return (this.connection != null ? this.connection.getClass() : MBeanServerConnection.class);
×
172
  }
173

174
  @Override
175
  public boolean isSingleton() {
176
    return true;
×
177
  }
178

179
  /**
180
   * Closes the underlying {@code JMXConnector}.
181
   */
182
  @Override
183
  public void destroy() throws IOException {
184
    if (this.connector != null &&
8!
185
            (this.connectorTargetSource == null || this.connectorTargetSource.isInitialized())) {
2!
186
      this.connector.close();
3✔
187
    }
188
  }
1✔
189

190
  /**
191
   * Lazily creates a {@code JMXConnector} using the configured service URL
192
   * and environment properties.
193
   *
194
   * @see MBeanServerConnectionFactoryBean#setServiceUrl(String)
195
   * @see MBeanServerConnectionFactoryBean#setEnvironment(Properties)
196
   */
197
  private final class JMXConnectorLazyInitTargetSource extends AbstractLazyCreationTargetSource {
6✔
198

199
    @Override
200
    protected Object createObject() throws Exception {
201
      Assert.state(serviceUrl != null, "No JMXServiceURL set");
×
202
      return JMXConnectorFactory.connect(serviceUrl, environment);
×
203
    }
204

205
    @Override
206
    public Class<?> getTargetClass() {
207
      return JMXConnector.class;
×
208
    }
209
  }
210

211
  /**
212
   * Lazily creates an {@code MBeanServerConnection}.
213
   */
214
  private final class MBeanServerConnectionLazyInitTargetSource extends AbstractLazyCreationTargetSource {
6✔
215

216
    @Override
217
    protected Object createObject() throws Exception {
218
      Assert.state(connector != null, "JMXConnector not initialized");
×
219
      return connector.getMBeanServerConnection();
×
220
    }
221

222
    @Override
223
    public Class<?> getTargetClass() {
224
      return MBeanServerConnection.class;
×
225
    }
226
  }
227

228
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc