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

TAKETODAY / today-infrastructure / 18154768944

01 Oct 2025 07:26AM UTC coverage: 81.882% (-0.005%) from 81.887%
18154768944

push

github

web-flow
Merge pull request #290 from TAKETODAY/dev/jspecify

jspecify

59788 of 78013 branches covered (76.64%)

Branch coverage included in aggregate %.

141239 of 167496 relevant lines covered (84.32%)

3.6 hits per line

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

85.11
today-context/src/main/java/infra/jndi/JndiObjectTargetSource.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.jndi;
19

20
import org.jspecify.annotations.Nullable;
21

22
import javax.naming.NamingException;
23

24
import infra.aop.TargetSource;
25
import infra.aop.framework.ProxyFactoryBean;
26

27
/**
28
 * AOP {@link infra.aop.TargetSource} that provides
29
 * configurable JNDI lookups for {@code getTarget()} calls.
30
 *
31
 * <p>Can be used as alternative to {@link JndiObjectFactoryBean}, to allow for
32
 * relocating a JNDI object lazily or for each operation (see "lookupOnStartup"
33
 * and "cache" properties). This is particularly useful during development, as it
34
 * allows for hot restarting of the JNDI server (for example, a remote JMS server).
35
 *
36
 * <p>Example:
37
 *
38
 * <pre class="code">
39
 * &lt;bean id="queueConnectionFactoryTarget" class="infra.jndi.JndiObjectTargetSource"&gt;
40
 *   &lt;property name="jndiName" value="JmsQueueConnectionFactory"/&gt;
41
 *   &lt;property name="lookupOnStartup" value="false"/&gt;
42
 * &lt;/bean&gt;
43
 *
44
 * &lt;bean id="queueConnectionFactory" class="infra.aop.framework.ProxyFactoryBean"&gt;
45
 *   &lt;property name="proxyInterfaces" value="jakarta.jms.QueueConnectionFactory"/&gt;
46
 *   &lt;property name="targetSource" ref="queueConnectionFactoryTarget"/&gt;
47
 * &lt;/bean&gt;</pre>
48
 *
49
 * A {@code createQueueConnection} call on the "queueConnectionFactory" proxy will
50
 * cause a lazy JNDI lookup for "JmsQueueConnectionFactory" and a subsequent delegating
51
 * call to the retrieved QueueConnectionFactory's {@code createQueueConnection}.
52
 *
53
 * <p><b>Alternatively, use a {@link JndiObjectFactoryBean} with a "proxyInterface".</b>
54
 * "lookupOnStartup" and "cache" can then be specified on the JndiObjectFactoryBean,
55
 * creating a JndiObjectTargetSource underneath (instead of defining separate
56
 * ProxyFactoryBean and JndiObjectTargetSource beans).
57
 *
58
 * @author Juergen Hoeller
59
 * @see #setLookupOnStartup
60
 * @see #setCache
61
 * @see ProxyFactoryBean#setTargetSource
62
 * @see JndiObjectFactoryBean#setProxyInterface
63
 * @since 4.0
64
 */
65
public class JndiObjectTargetSource extends JndiObjectLocator implements TargetSource {
2✔
66

67
  private boolean lookupOnStartup = true;
3✔
68

69
  private boolean cache = true;
4✔
70

71
  @Nullable
72
  private Object cachedObject;
73

74
  @Nullable
75
  private Class<?> targetClass;
76

77
  /**
78
   * Set whether to look up the JNDI object on startup. Default is "true".
79
   * <p>Can be turned off to allow for late availability of the JNDI object.
80
   * In this case, the JNDI object will be fetched on first access.
81
   *
82
   * @see #setCache
83
   */
84
  public void setLookupOnStartup(boolean lookupOnStartup) {
85
    this.lookupOnStartup = lookupOnStartup;
3✔
86
  }
1✔
87

88
  /**
89
   * Set whether to cache the JNDI object once it has been located.
90
   * Default is "true".
91
   * <p>Can be turned off to allow for hot redeployment of JNDI objects.
92
   * In this case, the JNDI object will be fetched for each invocation.
93
   *
94
   * @see #setLookupOnStartup
95
   */
96
  public void setCache(boolean cache) {
97
    this.cache = cache;
3✔
98
  }
1✔
99

100
  @Override
101
  public void afterPropertiesSet() throws NamingException {
102
    super.afterPropertiesSet();
2✔
103
    if (this.lookupOnStartup) {
3✔
104
      Object object = lookup();
3✔
105
      if (this.cache) {
3✔
106
        this.cachedObject = object;
4✔
107
      }
108
      else {
109
        this.targetClass = object.getClass();
4✔
110
      }
111
    }
112
  }
1✔
113

114
  @Override
115
  @Nullable
116
  public Class<?> getTargetClass() {
117
    if (this.cachedObject != null) {
3!
118
      return this.cachedObject.getClass();
×
119
    }
120
    else if (this.targetClass != null) {
3!
121
      return this.targetClass;
×
122
    }
123
    else {
124
      return getExpectedType();
3✔
125
    }
126
  }
127

128
  @Override
129
  public boolean isStatic() {
130
    return (this.cachedObject != null);
7✔
131
  }
132

133
  @Override
134
  @Nullable
135
  public Object getTarget() {
136
    try {
137
      if (this.lookupOnStartup || !this.cache) {
6✔
138
        return (this.cachedObject != null ? this.cachedObject : lookup());
9✔
139
      }
140
      else {
141
        synchronized(this) {
4✔
142
          if (this.cachedObject == null) {
3!
143
            this.cachedObject = lookup();
4✔
144
          }
145
          return this.cachedObject;
5✔
146
        }
147
      }
148
    }
149
    catch (NamingException ex) {
×
150
      throw new JndiLookupFailureException("JndiObjectTargetSource failed to obtain new target object", ex);
×
151
    }
152
  }
153

154
  @Override
155
  public void releaseTarget(Object target) { }
1✔
156

157
}
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