001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.context.event; 018 019import org.springframework.aop.support.AopUtils; 020import org.springframework.context.ApplicationEvent; 021import org.springframework.context.ApplicationListener; 022import org.springframework.core.Ordered; 023import org.springframework.core.ResolvableType; 024import org.springframework.util.Assert; 025 026/** 027 * {@link GenericApplicationListener} adapter that determines supported event types 028 * through introspecting the generically declared type of the target listener. 029 * 030 * @author Juergen Hoeller 031 * @author Stephane Nicoll 032 * @since 3.0 033 * @see org.springframework.context.ApplicationListener#onApplicationEvent 034 */ 035public class GenericApplicationListenerAdapter implements GenericApplicationListener, SmartApplicationListener { 036 037 private final ApplicationListener<ApplicationEvent> delegate; 038 039 private final ResolvableType declaredEventType; 040 041 042 /** 043 * Create a new GenericApplicationListener for the given delegate. 044 * @param delegate the delegate listener to be invoked 045 */ 046 @SuppressWarnings("unchecked") 047 public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) { 048 Assert.notNull(delegate, "Delegate listener must not be null"); 049 this.delegate = (ApplicationListener<ApplicationEvent>) delegate; 050 this.declaredEventType = resolveDeclaredEventType(this.delegate); 051 } 052 053 054 @Override 055 public void onApplicationEvent(ApplicationEvent event) { 056 this.delegate.onApplicationEvent(event); 057 } 058 059 @Override 060 @SuppressWarnings("unchecked") 061 public boolean supportsEventType(ResolvableType eventType) { 062 if (this.delegate instanceof SmartApplicationListener) { 063 Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve(); 064 return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass)); 065 } 066 else { 067 return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType)); 068 } 069 } 070 071 @Override 072 public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { 073 return supportsEventType(ResolvableType.forClass(eventType)); 074 } 075 076 @Override 077 public boolean supportsSourceType(Class<?> sourceType) { 078 return !(this.delegate instanceof SmartApplicationListener) || 079 ((SmartApplicationListener) this.delegate).supportsSourceType(sourceType); 080 } 081 082 @Override 083 public int getOrder() { 084 return (this.delegate instanceof Ordered ? ((Ordered) this.delegate).getOrder() : Ordered.LOWEST_PRECEDENCE); 085 } 086 087 088 static ResolvableType resolveDeclaredEventType(Class<?> listenerType) { 089 ResolvableType resolvableType = ResolvableType.forClass(listenerType).as(ApplicationListener.class); 090 return (resolvableType.hasGenerics() ? resolvableType.getGeneric() : null); 091 } 092 093 private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) { 094 ResolvableType declaredEventType = resolveDeclaredEventType(listener.getClass()); 095 if (declaredEventType == null || declaredEventType.isAssignableFrom( 096 ResolvableType.forClass(ApplicationEvent.class))) { 097 Class<?> targetClass = AopUtils.getTargetClass(listener); 098 if (targetClass != listener.getClass()) { 099 declaredEventType = resolveDeclaredEventType(targetClass); 100 } 101 } 102 return declaredEventType; 103 } 104 105}