2222
2323import org .springframework .aop .support .AopUtils ;
2424import org .springframework .beans .BeansException ;
25+ import org .springframework .beans .factory .BeanFactory ;
26+ import org .springframework .beans .factory .BeanFactoryAware ;
2527import org .springframework .beans .factory .BeanInitializationException ;
28+ import org .springframework .beans .factory .ListableBeanFactory ;
2629import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
30+ import org .springframework .beans .factory .SmartInitializingSingleton ;
2731import org .springframework .beans .factory .config .BeanPostProcessor ;
28- import org .springframework .context .ApplicationContext ;
29- import org .springframework .context .ApplicationContextAware ;
30- import org .springframework .context .ApplicationListener ;
3132import org .springframework .context .annotation .AnnotationConfigUtils ;
32- import org .springframework .context .event .ContextRefreshedEvent ;
3333import org .springframework .core .Ordered ;
3434import org .springframework .core .annotation .AnnotationUtils ;
3535import org .springframework .jms .config .DefaultJmsHandlerMethodFactory ;
3939import org .springframework .jms .config .JmsListenerEndpointRegistry ;
4040import org .springframework .jms .config .MethodJmsListenerEndpoint ;
4141import org .springframework .messaging .handler .invocation .InvocableHandlerMethod ;
42+ import org .springframework .util .Assert ;
4243import org .springframework .util .ReflectionUtils ;
4344import org .springframework .util .StringUtils ;
4445
6061 * {@link EnableJms} Javadoc for complete usage details.
6162 *
6263 * @author Stephane Nicoll
64+ * @author Juergen Hoeller
6365 * @since 4.1
6466 * @see JmsListener
6567 * @see EnableJms
6971 * @see org.springframework.jms.config.AbstractJmsListenerEndpoint
7072 * @see MethodJmsListenerEndpoint
7173 */
72- public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor , Ordered ,
73- ApplicationContextAware , ApplicationListener < ContextRefreshedEvent > {
74+ public class JmsListenerAnnotationBeanPostProcessor
75+ implements BeanPostProcessor , Ordered , BeanFactoryAware , SmartInitializingSingleton {
7476
7577 /**
76- * The bean name of the default {@link JmsListenerContainerFactory}
78+ * The bean name of the default {@link JmsListenerContainerFactory}.
7779 */
7880 static final String DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME = "jmsListenerContainerFactory" ;
7981
@@ -82,9 +84,9 @@ public class JmsListenerAnnotationBeanPostProcessor implements BeanPostProcessor
8284
8385 private String containerFactoryBeanName = DEFAULT_JMS_LISTENER_CONTAINER_FACTORY_BEAN_NAME ;
8486
85- private final JmsHandlerMethodFactoryAdapter jmsHandlerMethodFactory = new JmsHandlerMethodFactoryAdapter () ;
87+ private BeanFactory beanFactory ;
8688
87- private ApplicationContext applicationContext ;
89+ private final JmsHandlerMethodFactoryAdapter jmsHandlerMethodFactory = new JmsHandlerMethodFactoryAdapter () ;
8890
8991 private final JmsListenerEndpointRegistrar registrar = new JmsListenerEndpointRegistrar ();
9092
@@ -124,9 +126,50 @@ public void setJmsHandlerMethodFactory(JmsHandlerMethodFactory jmsHandlerMethodF
124126 this .jmsHandlerMethodFactory .setJmsHandlerMethodFactory (jmsHandlerMethodFactory );
125127 }
126128
129+ /**
130+ * Making a {@link BeanFactory} available is optional; if not set,
131+ * {@link JmsListenerConfigurer} beans won't get autodetected and an
132+ * {@link #setEndpointRegistry endpoint registry} has to be explicitly configured.
133+ */
134+ @ Override
135+ public void setBeanFactory (BeanFactory beanFactory ) {
136+ this .beanFactory = beanFactory ;
137+ }
138+
139+
127140 @ Override
128- public void setApplicationContext (ApplicationContext applicationContext ) {
129- this .applicationContext = applicationContext ;
141+ public void afterSingletonsInstantiated () {
142+ this .registrar .setBeanFactory (this .beanFactory );
143+
144+ if (this .beanFactory instanceof ListableBeanFactory ) {
145+ Map <String , JmsListenerConfigurer > instances =
146+ ((ListableBeanFactory ) this .beanFactory ).getBeansOfType (JmsListenerConfigurer .class );
147+ for (JmsListenerConfigurer configurer : instances .values ()) {
148+ configurer .configureJmsListeners (this .registrar );
149+ }
150+ }
151+
152+ if (this .registrar .getEndpointRegistry () == null ) {
153+ if (this .endpointRegistry == null ) {
154+ Assert .state (this .beanFactory != null , "BeanFactory must be set to find endpoint registry by bean name" );
155+ this .endpointRegistry = this .beanFactory .getBean (
156+ AnnotationConfigUtils .JMS_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME , JmsListenerEndpointRegistry .class );
157+ }
158+ this .registrar .setEndpointRegistry (this .endpointRegistry );
159+ }
160+
161+ if (this .containerFactoryBeanName != null ) {
162+ this .registrar .setContainerFactoryBeanName (this .containerFactoryBeanName );
163+ }
164+
165+ // Set the custom handler method factory once resolved by the configurer
166+ JmsHandlerMethodFactory handlerMethodFactory = this .registrar .getJmsHandlerMethodFactory ();
167+ if (handlerMethodFactory != null ) {
168+ this .jmsHandlerMethodFactory .setJmsHandlerMethodFactory (handlerMethodFactory );
169+ }
170+
171+ // Actually register all listeners
172+ this .registrar .afterPropertiesSet ();
130173 }
131174
132175
@@ -189,8 +232,9 @@ protected void processJmsListener(JmsListener jmsListener, Method method, Object
189232 JmsListenerContainerFactory <?> factory = null ;
190233 String containerFactoryBeanName = jmsListener .containerFactory ();
191234 if (StringUtils .hasText (containerFactoryBeanName )) {
235+ Assert .state (this .beanFactory != null , "BeanFactory must be set to obtain container factory by bean name" );
192236 try {
193- factory = this .applicationContext .getBean (containerFactoryBeanName , JmsListenerContainerFactory .class );
237+ factory = this .beanFactory .getBean (containerFactoryBeanName , JmsListenerContainerFactory .class );
194238 }
195239 catch (NoSuchBeanDefinitionException ex ) {
196240 throw new BeanInitializationException ("Could not register jms listener endpoint on [" +
@@ -199,49 +243,7 @@ protected void processJmsListener(JmsListener jmsListener, Method method, Object
199243 }
200244 }
201245
202- registrar .registerEndpoint (endpoint , factory );
203-
204- }
205-
206- @ Override
207- public void onApplicationEvent (ContextRefreshedEvent event ) {
208- if (event .getApplicationContext () != this .applicationContext ) {
209- return ;
210- }
211-
212- Map <String , JmsListenerConfigurer > instances =
213- this .applicationContext .getBeansOfType (JmsListenerConfigurer .class );
214- for (JmsListenerConfigurer configurer : instances .values ()) {
215- configurer .configureJmsListeners (registrar );
216- }
217-
218- this .registrar .setApplicationContext (this .applicationContext );
219-
220- if (this .registrar .getEndpointRegistry () == null ) {
221- if (this .endpointRegistry == null ) {
222- this .endpointRegistry = this .applicationContext .getBean (
223- AnnotationConfigUtils .JMS_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME , JmsListenerEndpointRegistry .class );
224- }
225- this .registrar .setEndpointRegistry (this .endpointRegistry );
226- }
227-
228- if (this .containerFactoryBeanName != null ) {
229- this .registrar .setContainerFactoryBeanName (this .containerFactoryBeanName );
230- }
231-
232- // Set the custom handler method factory once resolved by the configurer
233- JmsHandlerMethodFactory handlerMethodFactory = registrar .getJmsHandlerMethodFactory ();
234- if (handlerMethodFactory != null ) {
235- this .jmsHandlerMethodFactory .setJmsHandlerMethodFactory (handlerMethodFactory );
236- }
237-
238- // Create all the listeners and starts them
239- try {
240- this .registrar .afterPropertiesSet ();
241- }
242- catch (Exception ex ) {
243- throw new BeanInitializationException ("Failed to initialize JmsListenerEndpointRegistrar" , ex );
244- }
246+ this .registrar .registerEndpoint (endpoint , factory );
245247 }
246248
247249 private String getEndpointId (JmsListener jmsListener ) {
@@ -282,7 +284,7 @@ private JmsHandlerMethodFactory getJmsHandlerMethodFactory() {
282284
283285 private JmsHandlerMethodFactory createDefaultJmsHandlerMethodFactory () {
284286 DefaultJmsHandlerMethodFactory defaultFactory = new DefaultJmsHandlerMethodFactory ();
285- defaultFactory .setApplicationContext ( applicationContext );
287+ defaultFactory .setBeanFactory ( beanFactory );
286288 defaultFactory .afterPropertiesSet ();
287289 return defaultFactory ;
288290 }
0 commit comments