• 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

78.95
today-context/src/main/java/infra/context/event/EventPublicationInterceptor.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.context.event;
19

20
import org.aopalliance.intercept.MethodInterceptor;
21
import org.aopalliance.intercept.MethodInvocation;
22
import org.jspecify.annotations.Nullable;
23

24
import java.lang.reflect.Constructor;
25
import java.lang.reflect.Modifier;
26
import java.util.function.Supplier;
27

28
import infra.beans.factory.InitializingBean;
29
import infra.context.ApplicationEvent;
30
import infra.context.ApplicationEventPublisher;
31
import infra.context.ApplicationEventPublisherAware;
32
import infra.context.ApplicationListener;
33
import infra.lang.Assert;
34

35
/**
36
 * {@link MethodInterceptor Interceptor} that publishes an
37
 * {@code ApplicationEvent} to all {@code ApplicationListeners}
38
 * registered with an {@code ApplicationEventPublisher} after each
39
 * <i>successful</i> method invocation.
40
 *
41
 * @author Dmitriy Kopylenko
42
 * @author Juergen Hoeller
43
 * @author Rick Evans
44
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
45
 * @see #setApplicationEventClass
46
 * @see ApplicationEvent
47
 * @see ApplicationListener
48
 * @see ApplicationEventPublisher
49
 * @see infra.context.ApplicationContext
50
 * @since 4.0 2021/12/3 10:11
51
 */
52
public class EventPublicationInterceptor implements MethodInterceptor, ApplicationEventPublisherAware, InitializingBean {
3✔
53

54
  @Nullable
55
  private Constructor<?> applicationEventConstructor;
56

57
  @Nullable
58
  private ApplicationEventPublisher applicationEventPublisher;
59

60
  @Nullable
61
  private Supplier<?> applicationEventSupplier;
62

63
  /**
64
   * Set the application event class to publish.
65
   * <p>The event class <b>must</b> have a constructor with a single
66
   * {@code Object} argument for the event source. The interceptor
67
   * will pass in the invoked object.
68
   *
69
   * @throws IllegalArgumentException if the supplied {@code Class} is
70
   * {@code null} or if it is not an {@code ApplicationEvent} subclass or
71
   * if it does not expose a constructor that takes a single {@code Object} argument
72
   */
73
  public void setApplicationEventClass(Class<?> applicationEventClass) {
74
    if (Modifier.isAbstract(applicationEventClass.getModifiers())) {
4✔
75
      throw new IllegalArgumentException("'applicationEventClass' cannot be abstract");
5✔
76
    }
77
    try {
78
      this.applicationEventConstructor = applicationEventClass.getConstructor(Object.class);
10✔
79
    }
80
    catch (NoSuchMethodException ex) {
1✔
81
      throw new IllegalArgumentException("ApplicationEvent class [%s] does not have the required Object constructor: %s"
8✔
82
              .formatted(applicationEventClass.getName(), ex));
9✔
83
    }
1✔
84
  }
1✔
85

86
  /**
87
   * Set the event object supplier.
88
   */
89
  public void setApplicationEventSupplier(@Nullable Supplier<?> applicationEventSupplier) {
90
    this.applicationEventSupplier = applicationEventSupplier;
×
91
  }
×
92

93
  @Override
94
  public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
95
    this.applicationEventPublisher = applicationEventPublisher;
3✔
96
  }
1✔
97

98
  @Override
99
  public void afterPropertiesSet() throws Exception {
100
    if (applicationEventConstructor == null && applicationEventSupplier == null) {
6!
101
      throw new IllegalArgumentException("applicationEventConstructor and applicationEventSupplier must not be null at same time");
5✔
102
    }
103
  }
1✔
104

105
  @Override
106
  @Nullable
107
  public Object invoke(MethodInvocation invocation) throws Throwable {
108
    Object retVal = invocation.proceed();
3✔
109

110
    Assert.state(applicationEventPublisher != null, "No ApplicationEventPublisher available");
7!
111

112
    Object event = getEventObject(invocation);
4✔
113
    applicationEventPublisher.publishEvent(event);
4✔
114
    return retVal;
2✔
115
  }
116

117
  private Object getEventObject(MethodInvocation invocation) throws Exception {
118
    if (applicationEventSupplier != null) {
3!
119
      return applicationEventSupplier.get();
×
120
    }
121
    if (applicationEventConstructor != null) {
3!
122
      return applicationEventConstructor.newInstance(invocation.getThis());
11✔
123
    }
124
    throw new IllegalStateException("Event object cannot be determined");
×
125
  }
126

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