diff --git a/spring-context/src/main/java/org/springframework/scheduling/config/TriggerTask.java b/spring-context/src/main/java/org/springframework/scheduling/config/TriggerTask.java index 6d0aa6c813..0766d6580e 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/config/TriggerTask.java +++ b/spring-context/src/main/java/org/springframework/scheduling/config/TriggerTask.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,8 +19,8 @@ package org.springframework.scheduling.config; import org.springframework.scheduling.Trigger; /** - * {@link Task} implementation defining a {@code Runnable} to be executed according to a - * given {@link Trigger}. + * {@link Task} implementation defining a {@code Runnable} to be executed + * according to a given {@link Trigger}. * * @author Chris Beams * @since 3.2 @@ -45,6 +45,7 @@ public class TriggerTask extends Task { public Trigger getTrigger() { - return trigger; + return this.trigger; } + } diff --git a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java index bda5965ed6..10b35b7ea1 100644 --- a/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java +++ b/spring-jms/src/main/java/org/springframework/jms/annotation/JmsListenerAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -198,8 +198,8 @@ public class JmsListenerAnnotationBeanPostProcessor new MethodIntrospector.MetadataLookup>() { @Override public Set inspect(Method method) { - Set listenerMethods = - AnnotationUtils.getRepeatableAnnotations(method, JmsListener.class, JmsListeners.class); + Set listenerMethods = AnnotationUtils.getRepeatableAnnotations( + method, JmsListener.class, JmsListeners.class); return (!listenerMethods.isEmpty() ? listenerMethods : null); } }); @@ -293,15 +293,9 @@ public class JmsListenerAnnotationBeanPostProcessor } } - /** - * Resolve the specified value if possible. - * @see ConfigurableBeanFactory#resolveEmbeddedValue - */ private String resolve(String value) { - if (this.beanFactory instanceof ConfigurableBeanFactory) { - return ((ConfigurableBeanFactory) this.beanFactory).resolveEmbeddedValue(value); - } - return value; + return (this.beanFactory instanceof ConfigurableBeanFactory ? + ((ConfigurableBeanFactory) this.beanFactory).resolveEmbeddedValue(value) : value); } diff --git a/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistrar.java b/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistrar.java index f965a64d1f..af540e59a7 100644 --- a/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistrar.java +++ b/spring-jms/src/main/java/org/springframework/jms/config/JmsListenerEndpointRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -136,7 +136,7 @@ public class JmsListenerEndpointRegistrar implements BeanFactoryAware, Initializ this.endpointRegistry.registerListenerContainer( descriptor.endpoint, resolveContainerFactory(descriptor)); } - startImmediately = true; // trigger immediate startup + this.startImmediately = true; // trigger immediate startup } } @@ -149,9 +149,10 @@ public class JmsListenerEndpointRegistrar implements BeanFactoryAware, Initializ } else if (this.containerFactoryBeanName != null) { Assert.state(this.beanFactory != null, "BeanFactory must be set to obtain container factory by bean name"); + // Consider changing this if live change of the factory is required... this.containerFactory = this.beanFactory.getBean( this.containerFactoryBeanName, JmsListenerContainerFactory.class); - return this.containerFactory; // Consider changing this if live change of the factory is required + return this.containerFactory; } else { throw new IllegalStateException("Could not resolve the " + @@ -169,10 +170,12 @@ public class JmsListenerEndpointRegistrar implements BeanFactoryAware, Initializ public void registerEndpoint(JmsListenerEndpoint endpoint, JmsListenerContainerFactory factory) { Assert.notNull(endpoint, "Endpoint must be set"); Assert.hasText(endpoint.getId(), "Endpoint id must be set"); + // Factory may be null, we defer the resolution right before actually creating the container JmsListenerEndpointDescriptor descriptor = new JmsListenerEndpointDescriptor(endpoint, factory); + synchronized (this.mutex) { - if (startImmediately) { // Register and start immediately + if (this.startImmediately) { // register and start immediately this.endpointRegistry.registerListenerContainer(descriptor.endpoint, resolveContainerFactory(descriptor), true); } diff --git a/src/test/java/org/springframework/scheduling/annotation/ScheduledAndTransactionalAnnotationIntegrationTests.java b/src/test/java/org/springframework/scheduling/annotation/ScheduledAndTransactionalAnnotationIntegrationTests.java index 318fa211b7..1a0f250d86 100644 --- a/src/test/java/org/springframework/scheduling/annotation/ScheduledAndTransactionalAnnotationIntegrationTests.java +++ b/src/test/java/org/springframework/scheduling/annotation/ScheduledAndTransactionalAnnotationIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.junit.Before; import org.junit.Test; + import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.BeanCreationException; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -55,13 +56,14 @@ public class ScheduledAndTransactionalAnnotationIntegrationTests { Assume.group(TestGroup.PERFORMANCE); } + @Test public void failsWhenJdkProxyAndScheduledMethodNotPresentOnInterface() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(Config.class, JdkProxyTxConfig.class, RepoConfigA.class); try { ctx.refresh(); - fail("expected exception"); + fail("Should have thrown BeanCreationException"); } catch (BeanCreationException ex) { assertTrue(ex.getRootCause().getMessage().startsWith("@Scheduled method 'scheduled' found")); @@ -101,28 +103,36 @@ public class ScheduledAndTransactionalAnnotationIntegrationTests { @Configuration @EnableTransactionManagement - static class JdkProxyTxConfig { } + static class JdkProxyTxConfig { + } + @Configuration @EnableTransactionManagement(proxyTargetClass=true) - static class SubclassProxyTxConfig { } + static class SubclassProxyTxConfig { + } + @Configuration static class RepoConfigA { + @Bean public MyRepository repository() { return new MyRepositoryImpl(); } } + @Configuration static class RepoConfigB { + @Bean public MyRepositoryWithScheduledMethod repository() { return new MyRepositoryWithScheduledMethodImpl(); } } + @Configuration @EnableScheduling static class Config { @@ -139,15 +149,17 @@ public class ScheduledAndTransactionalAnnotationIntegrationTests { @Bean public PersistenceExceptionTranslator peTranslator() { - PersistenceExceptionTranslator txlator = mock(PersistenceExceptionTranslator.class); - return txlator; + return mock(PersistenceExceptionTranslator.class); } } + public interface MyRepository { + int getInvocationCount(); } + @Repository static class MyRepositoryImpl implements MyRepository { @@ -165,11 +177,15 @@ public class ScheduledAndTransactionalAnnotationIntegrationTests { } } + public interface MyRepositoryWithScheduledMethod { + int getInvocationCount(); - public void scheduled(); + + void scheduled(); } + @Repository static class MyRepositoryWithScheduledMethodImpl implements MyRepositoryWithScheduledMethod {