下面列出了怎么用org.springframework.context.ApplicationListener的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
@Test
public void should_start_job_from_github_push_event() throws Exception {
String yml = StringHelper.toString(load("flow.yml"));
flowMockHelper.create("github-test", yml);
String payload = StringHelper.toString(load("github/webhook_push.json"));
CountDownLatch waitForJobCreated = new CountDownLatch(1);
ObjectWrapper<Job> jobCreated = new ObjectWrapper<>();
addEventListener((ApplicationListener<JobCreatedEvent>) event -> {
jobCreated.setValue(event.getJob());
waitForJobCreated.countDown();
});
mockMvcHelper.expectSuccessAndReturnString(
post("/webhooks/github-test")
.header("X-GitHub-Event", "push")
.contentType(MediaType.APPLICATION_JSON)
.content(payload));
Assert.assertTrue(waitForJobCreated.await(10, TimeUnit.SECONDS));
Assert.assertNotNull(jobCreated.getValue());
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
@Test
public void should_add_cron_task() throws IOException, InterruptedException {
InputStream stream = load("flow-with-cron.yml");
Flow flow = flowService.create("cron-test");
ymlService.saveYml(flow, StringHelper.toString(stream));
final CountDownLatch counter = new CountDownLatch(2);
final ObjectWrapper<Flow> result = new ObjectWrapper<>();
addEventListener((ApplicationListener<CreateNewJobEvent>) event -> {
result.setValue(event.getFlow());
counter.countDown();
});
counter.await();
Assert.assertNotNull(result.getValue());
Assert.assertEquals(flow, result.getValue());
}
@Test
public void should_not_start_job_form_github_push_event_since_branch_not_match() throws Exception {
String yml = StringHelper.toString(load("flow-with-filter.yml"));
flowMockHelper.create("github-test", yml);
String payload = StringHelper.toString(load("github/webhook_push.json"));
CountDownLatch waitForJobCreated = new CountDownLatch(1);
ObjectWrapper<Job> jobCreated = new ObjectWrapper<>();
addEventListener((ApplicationListener<JobCreatedEvent>) event -> {
jobCreated.setValue(event.getJob());
waitForJobCreated.countDown();
});
mockMvcHelper.expectSuccessAndReturnString(
post("/webhooks/github-test")
.header("X-GitHub-Event", "push")
.contentType(MediaType.APPLICATION_JSON)
.content(payload));
Assert.assertFalse(waitForJobCreated.await(1, TimeUnit.SECONDS));
Assert.assertNull(jobCreated.getValue());
}
/**
* Checks that globals get invoked,
* and that they can add aspect interfaces unavailable
* to other beans. These interfaces don't need
* to be included in proxiedInterface [].
*/
@Test
public void testGlobalsCanAddAspectInterfaces() {
AddedGlobalInterface agi = (AddedGlobalInterface) factory.getBean("autoInvoker");
assertTrue(agi.globalsAdded() == -1);
ProxyFactoryBean pfb = (ProxyFactoryBean) factory.getBean("&validGlobals");
// Trigger lazy initialization.
pfb.getObject();
// 2 globals + 2 explicit
assertEquals("Have 2 globals and 2 explicit advisors", 3, pfb.getAdvisors().length);
ApplicationListener<?> l = (ApplicationListener<?>) factory.getBean("validGlobals");
agi = (AddedGlobalInterface) l;
assertTrue(agi.globalsAdded() == -1);
try {
agi = (AddedGlobalInterface) factory.getBean("test1");
fail("Aspect interface should't be implemeneted without globals");
}
catch (ClassCastException ex) {
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (flag == null) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.put(beanName, Boolean.FALSE);
}
}
return bean;
}
private void multicastEvent(boolean match, Class<?> listenerType, ApplicationEvent event, ResolvableType eventType) {
@SuppressWarnings("unchecked")
ApplicationListener<ApplicationEvent> listener =
(ApplicationListener<ApplicationEvent>) mock(listenerType);
SimpleApplicationEventMulticaster smc = new SimpleApplicationEventMulticaster();
smc.addApplicationListener(listener);
if (eventType != null) {
smc.multicastEvent(event, eventType);
}
else {
smc.multicastEvent(event);
}
int invocation = match ? 1 : 0;
verify(listener, times(invocation)).onApplicationEvent(event);
}
public static <T> T getOrCreateBean(
final ConfigurableApplicationContext ctx,
final String actualClazz,
final Class<T> type) throws ClassNotFoundException {
T bean;
if (ctx.getBeanFactory().containsSingleton(actualClazz)) {
bean = type.cast(ctx.getBeanFactory().getSingleton(actualClazz));
} else {
if (ApplicationListener.class.isAssignableFrom(type)) {
RootBeanDefinition bd = new RootBeanDefinition(
Class.forName(actualClazz), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false);
bd.setScope(BeanDefinition.SCOPE_SINGLETON);
((BeanDefinitionRegistry) ctx.getBeanFactory()).registerBeanDefinition(actualClazz, bd);
bean = ctx.getBean(type);
} else {
bean = type.cast(ctx.getBeanFactory().
createBean(Class.forName(actualClazz), AbstractBeanDefinition.AUTOWIRE_BY_TYPE, false));
ctx.getBeanFactory().registerSingleton(actualClazz, bean);
}
}
return bean;
}
@Test
@SuppressWarnings("unchecked")
public void proxiedListeners() {
MyOrderedListener1 listener1 = new MyOrderedListener1();
MyOrderedListener2 listener2 = new MyOrderedListener2(listener1);
ApplicationListener<ApplicationEvent> proxy1 = (ApplicationListener<ApplicationEvent>) new ProxyFactory(listener1).getProxy();
ApplicationListener<ApplicationEvent> proxy2 = (ApplicationListener<ApplicationEvent>) new ProxyFactory(listener2).getProxy();
SimpleApplicationEventMulticaster smc = new SimpleApplicationEventMulticaster();
smc.addApplicationListener(proxy1);
smc.addApplicationListener(proxy2);
smc.multicastEvent(new MyEvent(this));
smc.multicastEvent(new MyOtherEvent(this));
assertEquals(2, listener1.seenEvents.size());
}
@Test
public void lambdaAsListenerWithErrorHandler() {
final Set<MyEvent> seenEvents = new HashSet<>();
StaticApplicationContext context = new StaticApplicationContext();
SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster();
multicaster.setErrorHandler(ReflectionUtils::rethrowRuntimeException);
context.getBeanFactory().registerSingleton(
StaticApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME, multicaster);
ApplicationListener<MyEvent> listener = seenEvents::add;
context.addApplicationListener(listener);
context.refresh();
MyEvent event1 = new MyEvent(context);
context.publishEvent(event1);
context.publishEvent(new MyOtherEvent(context));
MyEvent event2 = new MyEvent(context);
context.publishEvent(event2);
assertSame(2, seenEvents.size());
assertTrue(seenEvents.contains(event1));
assertTrue(seenEvents.contains(event2));
context.close();
}
private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
ApplicationListener<ApplicationReadyEvent> readyListener=new ApplicationListener<ApplicationReadyEvent> () {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
ConfigurableApplicationContext context = event.getApplicationContext();
UserMapper userMapper=context.getBean(UserMapper.class);
userMapper.allUsers();
UserCondition condition = new UserCondition();
PageRequest page =new PageRequest(1, 10);
condition.setPageable(page);
condition.setStatus(1);
userMapper.listByCondition(condition);
}
};
return builder.sources(CacheDemoApplication.class).bannerMode(Banner.Mode.OFF).listeners(readyListener);
}
public static void main(String[] args) throws IOException {
GenericApplicationContext context = new GenericApplicationContext();
context.addApplicationListener(new ApplicationListener<ContextClosedEvent>() {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
System.out.printf("[线程 %s] ContextClosedEvent 处理\n", Thread.currentThread().getName());
}
});
// 刷新 Spring 应用上下文
context.refresh();
// 注册 Shutdown Hook
context.registerShutdownHook();
System.out.println("按任意键继续并且关闭 Spring 应用上下文");
System.in.read();
// 关闭 Spring 应用(同步)
context.close();
}
@Test
public void should_not_start_job_form_github_push_event_since_branch_not_match() throws Exception {
String yml = StringHelper.toString(load("flow-with-filter.yml"));
flowMockHelper.create("github-test", yml);
String payload = StringHelper.toString(load("github/webhook_push.json"));
CountDownLatch waitForJobCreated = new CountDownLatch(1);
ObjectWrapper<Job> jobCreated = new ObjectWrapper<>();
addEventListener((ApplicationListener<JobCreatedEvent>) event -> {
jobCreated.setValue(event.getJob());
waitForJobCreated.countDown();
});
mockMvcHelper.expectSuccessAndReturnString(
post("/webhooks/github-test")
.header("X-GitHub-Event", "push")
.contentType(MediaType.APPLICATION_JSON)
.content(payload));
Assert.assertFalse(waitForJobCreated.await(1, TimeUnit.SECONDS));
Assert.assertNull(jobCreated.getValue());
}
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
public static void main(String[] args) {
SpringApplicationBuilder builder = new SpringApplicationBuilder(Launcher.class);
Set<ApplicationListener<?>> listeners = builder.application().getListeners();
for (Iterator<ApplicationListener<?>> it = listeners.iterator(); it.hasNext();) {
ApplicationListener<?> listener = it.next();
if (listener instanceof LoggingApplicationListener) {
it.remove();
}
}
builder.application().setListeners(listeners);
ConfigurableApplicationContext context = builder.run(args);
LOGGER.info("collector metrics start successfully");
KafkaConsumer kafkaConsumer = (KafkaConsumer<byte[], String>) context.getBean("kafkaConsumer");
Task task = (Task) context.getBean("metricsTask");
// 优雅停止项目
Runtime.getRuntime().addShutdownHook(new ShutdownHookRunner(kafkaConsumer, task));
task.doTask();
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (this.applicationContext != null && bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
public Collection<ApplicationListener<?>> getApplicationListeners() {
List<ApplicationListener<?>> allListeners = new ArrayList<>(
this.applicationListeners.size() + this.applicationListenerBeans.size());
allListeners.addAll(this.applicationListeners);
if (!this.applicationListenerBeans.isEmpty()) {
BeanFactory beanFactory = getBeanFactory();
for (String listenerBeanName : this.applicationListenerBeans) {
try {
ApplicationListener<?> listener = beanFactory.getBean(listenerBeanName, ApplicationListener.class);
if (this.preFiltered || !allListeners.contains(listener)) {
allListeners.add(listener);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Singleton listener instance (without backing bean definition) disappeared -
// probably in the middle of the destruction phase
}
}
}
if (!this.preFiltered || !this.applicationListenerBeans.isEmpty()) {
AnnotationAwareOrderComparator.sort(allListeners);
}
return allListeners;
}
@Test
public void simpleApplicationEventMulticasterWithTaskExecutor() {
@SuppressWarnings("unchecked")
ApplicationListener<ApplicationEvent> listener = mock(ApplicationListener.class);
ApplicationEvent evt = new ContextClosedEvent(new StaticApplicationContext());
SimpleApplicationEventMulticaster smc = new SimpleApplicationEventMulticaster();
smc.setTaskExecutor(new Executor() {
@Override
public void execute(Runnable command) {
command.run();
command.run();
}
});
smc.addApplicationListener(listener);
smc.multicastEvent(evt);
verify(listener, times(2)).onApplicationEvent(evt);
}
@Test
public void simpleApplicationEventMulticasterWithException() {
@SuppressWarnings("unchecked")
ApplicationListener<ApplicationEvent> listener = mock(ApplicationListener.class);
ApplicationEvent evt = new ContextClosedEvent(new StaticApplicationContext());
SimpleApplicationEventMulticaster smc = new SimpleApplicationEventMulticaster();
smc.addApplicationListener(listener);
RuntimeException thrown = new RuntimeException();
willThrow(thrown).given(listener).onApplicationEvent(evt);
try {
smc.multicastEvent(evt);
fail("Should have thrown RuntimeException");
}
catch (RuntimeException ex) {
assertSame(thrown, ex);
}
}
@Test
public void testRemoveConfigWithEvent() throws NacosException {
context.addApplicationListener(
new ApplicationListener<NacosConfigRemovedEvent>() {
@Override
public void onApplicationEvent(NacosConfigRemovedEvent event) {
assertNacosConfigEvent(event);
Assert.assertTrue(event.isRemoved());
}
});
configService.publishConfig(DATA_ID, GROUP_ID, CONTENT);
configService.removeConfig(DATA_ID, GROUP_ID);
}
@Test
public void lambdaAsListener() {
final Set<MyEvent> seenEvents = new HashSet<>();
StaticApplicationContext context = new StaticApplicationContext();
ApplicationListener<MyEvent> listener = seenEvents::add;
context.addApplicationListener(listener);
context.refresh();
MyEvent event1 = new MyEvent(context);
context.publishEvent(event1);
context.publishEvent(new MyOtherEvent(context));
MyEvent event2 = new MyEvent(context);
context.publishEvent(event2);
assertSame(2, seenEvents.size());
assertTrue(seenEvents.contains(event1));
assertTrue(seenEvents.contains(event2));
context.close();
}
@Test
@SuppressWarnings("unchecked")
public void proxiedListeners() {
MyOrderedListener1 listener1 = new MyOrderedListener1();
MyOrderedListener2 listener2 = new MyOrderedListener2(listener1);
ApplicationListener<ApplicationEvent> proxy1 = (ApplicationListener<ApplicationEvent>) new ProxyFactory(listener1).getProxy();
ApplicationListener<ApplicationEvent> proxy2 = (ApplicationListener<ApplicationEvent>) new ProxyFactory(listener2).getProxy();
SimpleApplicationEventMulticaster smc = new SimpleApplicationEventMulticaster();
smc.addApplicationListener(proxy1);
smc.addApplicationListener(proxy2);
smc.multicastEvent(new MyEvent(this));
smc.multicastEvent(new MyOtherEvent(this));
assertEquals(2, listener1.seenEvents.size());
}
@Bean
public ApplicationListener<EmbeddedServletContainerInitializedEvent> getApplicationListenerEmbeddedServletContainerInitializedEvent() {
return new ApplicationListener<EmbeddedServletContainerInitializedEvent>() {
@Override
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
int serverPort = event.getEmbeddedServletContainer().getPort();
logger.debug("Saving port number = {}", serverPort);
resttemplateConfig.setPort(serverPort);
}
};
}
protected void disableEventListeners() {
Frame wrapper = getWrapper();
if (wrapper != null) {
List<ApplicationListener> uiEventListeners = ((AbstractFrame) wrapper).getUiEventListeners();
if (uiEventListeners != null) {
for (ApplicationListener listener : uiEventListeners) {
UiEventsMulticaster multicaster = App.getInstance().getUiEventsMulticaster();
multicaster.removeApplicationListener(listener);
}
}
}
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
try {
ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
multicaster.removeApplicationListener((ApplicationListener<?>) bean);
multicaster.removeApplicationListenerBean(beanName);
}
catch (IllegalStateException ex) {
// ApplicationEventMulticaster not initialized yet - no need to remove a listener
}
}
}
/**
* Create a new GenericApplicationListener for the given delegate.
* @param delegate the delegate listener to be invoked
*/
@SuppressWarnings("unchecked")
public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) {
Assert.notNull(delegate, "Delegate listener must not be null");
this.delegate = (ApplicationListener<ApplicationEvent>) delegate;
this.declaredEventType = resolveDeclaredEventType(this.delegate);
}
/**
* Create a new GenericApplicationListener for the given delegate.
* @param delegate the delegate listener to be invoked
*/
@SuppressWarnings("unchecked")
public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) {
Assert.notNull(delegate, "Delegate listener must not be null");
this.delegate = (ApplicationListener<ApplicationEvent>) delegate;
this.declaredEventType = resolveDeclaredEventType(this.delegate);
}
public static void main(String[] args) {
new SpringApplicationBuilder(Object.class)
.listeners(
// event -> { // 取消所有 Spring Boot 事件监听
(ApplicationListener<ApplicationReadyEvent>) event -> {
throw new ExitCodeGeneratorThrowable(event.getClass().getSimpleName());
})
.web(false) // 非 Web 应用
.run(args) // 运行 SpringApplication
.close(); // 关闭 ConfigurableApplicationContext
}
@Override
public void multicastEvent(ApplicationEvent event) {
Object source = event.getSource();
Class<?> sourceType = (source != null ? source.getClass() : null);
ResolvableType type = resolveDefaultEventType(event);
for (ApplicationListener<?> listener : retrieveApplicationListeners(type, sourceType)) {
invokeListener(listener, event);
}
}