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

TAKETODAY / today-infrastructure / 16831772395

08 Aug 2025 01:34PM UTC coverage: 81.78% (+0.002%) from 81.778%
16831772395

push

github

TAKETODAY
:bug: 修复 OnWebApplicationCondition isReactiveWebApplication

59512 of 77727 branches covered (76.57%)

Branch coverage included in aggregate %.

140817 of 167235 relevant lines covered (84.2%)

3.6 hits per line

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

95.24
today-context/src/main/java/infra/context/support/ApplicationObjectSupport.java
1
/*
2
 * Copyright 2017 - 2024 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.context.support;
19

20
import infra.beans.BeansException;
21
import infra.context.ApplicationContext;
22
import infra.context.ApplicationContextAware;
23
import infra.context.ApplicationContextException;
24
import infra.lang.Assert;
25
import infra.lang.Nullable;
26
import infra.logging.Logger;
27
import infra.logging.LoggerFactory;
28

29
/**
30
 * Convenient superclass for application objects that want to be aware of
31
 * the application context, e.g. for custom lookup of collaborating beans
32
 * or for context-specific resource access. It saves the application
33
 * context reference and provides an initialization callback method.
34
 * Furthermore, it offers numerous convenience methods for message lookup.
35
 *
36
 * <p>There is no requirement to subclass this class: It just makes things
37
 * a little easier if you need access to the context, e.g. for access to
38
 * file resources or to the message source. Note that many application
39
 * objects do not need to be aware of the application context at all,
40
 * as they can receive collaborating beans via bean references.
41
 *
42
 * <p>Many framework classes are derived from this class, particularly
43
 * within the web support.
44
 *
45
 * @author Rod Johnson
46
 * @author Juergen Hoeller
47
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
48
 * @since 2019-12-21 15:45
49
 */
50
public abstract class ApplicationObjectSupport implements ApplicationContextAware {
2✔
51

52
  protected final Logger logger = LoggerFactory.getLogger(getClass());
6✔
53

54
  @Nullable
55
  protected ApplicationContext applicationContext;
56

57
  /** MessageSourceAccessor for easy message access. @since 4.0 */
58
  @Nullable
59
  protected MessageSourceAccessor messageSourceAccessor;
60

61
  @Override
62
  public final void setApplicationContext(@Nullable ApplicationContext context) throws BeansException {
63
    if (context == null && !isContextRequired()) {
5✔
64
      // Reset internal context state.
65
      this.applicationContext = null;
3✔
66
      this.messageSourceAccessor = null;
4✔
67
    }
68
    else if (this.applicationContext == null) {
3✔
69
      // Initialize with passed-in context.
70
      if (!requiredContextClass().isInstance(context)) {
5✔
71
        throw new ApplicationContextException(
8✔
72
                "Invalid application context: needs to be of type [%s]".formatted(requiredContextClass().getName()));
6✔
73
      }
74
      this.applicationContext = context;
3✔
75
      initApplicationContext(context);
4✔
76
    }
77
    else {
78
      // Ignore reinitialization if same context passed in.
79
      if (this.applicationContext != context) {
4✔
80
        throw new ApplicationContextException("Cannot reinitialize with different application context: current one is [%s], passed-in one is [%s]"
14✔
81
                .formatted(this.applicationContext, context));
3✔
82
      }
83
    }
84
  }
1✔
85

86
  /**
87
   * Subclasses can override this for custom initialization behavior. Gets called
88
   * by {@code setApplicationContext} after setting the context instance.
89
   * <p>
90
   * Note: Does <i>not</i> get called on re-initialization of the context but
91
   * rather just on first initialization of this object's context reference.
92
   * <p>
93
   * The default implementation calls the overloaded
94
   * {@link #initApplicationContext()} method without ApplicationContext
95
   * reference.
96
   *
97
   * @param context the containing ApplicationContext
98
   * @throws ApplicationContextException if thrown by ApplicationContext methods
99
   * @see #setApplicationContext
100
   */
101
  protected void initApplicationContext(ApplicationContext context) {
102
    initApplicationContext();
2✔
103
  }
1✔
104

105
  /**
106
   * Subclasses can override this for custom initialization behavior.
107
   * <p>
108
   * The default implementation is empty. Called by
109
   * {@link #initApplicationContext(ApplicationContext)}.
110
   *
111
   * @throws ApplicationContextException if thrown by ApplicationContext methods
112
   * @see #setApplicationContext
113
   */
114
  protected void initApplicationContext() {
115
  }
1✔
116

117
  /**
118
   * Return the ApplicationContext that this object is associated with.
119
   *
120
   * @throws IllegalStateException if not running in an ApplicationContext
121
   */
122
  @Nullable
123
  public final ApplicationContext getApplicationContext() throws IllegalStateException {
124
    ApplicationContext context = this.applicationContext;
3✔
125
    if (context == null && isContextRequired()) {
5!
126
      throw new IllegalStateException(
×
127
              "ApplicationContextSupport instance [%s] does not run in an ApplicationContext".formatted(this));
×
128
    }
129
    return context;
2✔
130
  }
131

132
  /**
133
   * Return the ApplicationContext that this object is associated with.
134
   *
135
   * @throws IllegalStateException if not running in an ApplicationContext
136
   */
137
  public ApplicationContext obtainApplicationContext() {
138
    final ApplicationContext context = this.applicationContext;
3✔
139
    Assert.state(context != null, "No ApplicationContext");
7✔
140
    return context;
2✔
141
  }
142

143
  /**
144
   * unwrap bean-factory to {@code requiredType}
145
   *
146
   * @throws IllegalArgumentException not a requiredType
147
   * @see ApplicationContext#getBeanFactory()
148
   * @since 4.0
149
   */
150
  public <T> T unwrapFactory(Class<T> requiredType) {
151
    return obtainApplicationContext().unwrapFactory(requiredType);
5✔
152
  }
153

154
  /**
155
   * unwrap this ApplicationContext to {@code requiredType}
156
   *
157
   * @throws IllegalArgumentException not a requiredType
158
   * @since 4.0
159
   */
160
  public <T> T unwrapContext(Class<T> requiredType) {
161
    return obtainApplicationContext().unwrap(requiredType);
5✔
162
  }
163

164
  /**
165
   * Return a MessageSourceAccessor for the application context
166
   * used by this object, for easy message access.
167
   *
168
   * @throws IllegalStateException if not running in an ApplicationContext
169
   * @since 4.0
170
   */
171
  @Nullable
172
  protected final MessageSourceAccessor getMessageSourceAccessor() throws IllegalStateException {
173
    MessageSourceAccessor accessor = this.messageSourceAccessor;
3✔
174
    if (accessor == null) {
2✔
175
      ApplicationContext context = this.applicationContext;
3✔
176
      if (context == null) {
2✔
177
        if (isContextRequired()) {
3✔
178
          throw new IllegalStateException(
9✔
179
                  "ApplicationObjectSupport instance [%s] does not run in an ApplicationContext".formatted(this));
3✔
180
        }
181
        return null;
2✔
182
      }
183
      else {
184
        accessor = new MessageSourceAccessor(context);
5✔
185
        this.messageSourceAccessor = accessor;
3✔
186
      }
187
    }
188

189
    return accessor;
2✔
190
  }
191

192
  /**
193
   * Determine whether this application object needs to run in an ApplicationContext.
194
   * <p>Default is "false". Can be overridden to enforce running in a context
195
   * (i.e. to throw IllegalStateException on accessors if outside a context).
196
   *
197
   * @see #getApplicationContext
198
   * @see #getMessageSourceAccessor
199
   * @since 4.0
200
   */
201
  protected boolean isContextRequired() {
202
    return false;
2✔
203
  }
204

205
  /**
206
   * Determine the context class that any context passed to
207
   * {@code setApplicationContext} must be an instance of.
208
   * Can be overridden in subclasses.
209
   *
210
   * @see #setApplicationContext
211
   * @since 4.0
212
   */
213
  protected Class<?> requiredContextClass() {
214
    return ApplicationContext.class;
2✔
215
  }
216
}
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