Polishing

This commit is contained in:
Juergen Hoeller
2015-07-30 17:52:33 +02:00
parent ce50fc59ee
commit 7575271075
45 changed files with 597 additions and 529 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2015 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.
@@ -25,10 +25,10 @@ import org.springframework.util.Assert;
/**
* A {@link ScopeMetadataResolver} implementation that by default checks for
* the presence of Spring's {@link Scope} annotation on the bean class.
* the presence of Spring's {@link Scope @Scope} annotation on the bean class.
*
* <p>The exact type of annotation that is checked for is configurable via the
* {@link #setScopeAnnotationType(Class)} property.
* <p>The exact type of annotation that is checked for is configurable via
* {@link #setScopeAnnotationType(Class)}.
*
* @author Mark Fisher
* @author Juergen Hoeller
@@ -43,7 +43,7 @@ public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {
/**
* Create a new instance of the {@code AnnotationScopeMetadataResolver} class.
* Construct a new {@code AnnotationScopeMetadataResolver}.
* @see #AnnotationScopeMetadataResolver(ScopedProxyMode)
* @see ScopedProxyMode#NO
*/
@@ -52,8 +52,9 @@ public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {
}
/**
* Create a new instance of the {@code AnnotationScopeMetadataResolver} class.
* @param defaultProxyMode the desired scoped-proxy mode
* Construct a new {@code AnnotationScopeMetadataResolver} using the
* supplied default {@link ScopedProxyMode}.
* @param defaultProxyMode the default scoped-proxy mode
*/
public AnnotationScopeMetadataResolver(ScopedProxyMode defaultProxyMode) {
Assert.notNull(defaultProxyMode, "'defaultProxyMode' must not be null");
@@ -63,7 +64,7 @@ public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {
/**
* Set the type of annotation that is checked for by this
* {@link AnnotationScopeMetadataResolver}.
* {@code AnnotationScopeMetadataResolver}.
* @param scopeAnnotationType the target annotation type
*/
public void setScopeAnnotationType(Class<? extends Annotation> scopeAnnotationType) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -138,11 +138,11 @@ import org.springframework.core.Ordered;
public @interface EnableAsync {
/**
* Indicate the 'async' annotation type to be detected at either class
* or method level. By default, both the {@link Async} annotation and
* the EJB 3.1 {@code javax.ejb.Asynchronous} annotation will be
* detected. <p>This setter property exists so that developers can provide
* their own (non-Spring-specific) annotation type to indicate that a method
* Indicate the 'async' annotation type to be detected at either class or
* method level. By default, both the {@link Async} annotation and the
* EJB 3.1 {@code javax.ejb.Asynchronous} annotation will be detected.
* <p>This setter property exists so that developers can provide their
* own (non-Spring-specific) annotation type to indicate that a method
* (or all methods of a given class) should be invoked asynchronously.
*/
Class<? extends Annotation> annotation() default Annotation.class;
@@ -151,7 +151,6 @@ public @interface EnableAsync {
* Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
* to standard Java interface-based proxies. The default is {@code false}. <strong>
* Applicable only if {@link #mode()} is set to {@link AdviceMode#PROXY}</strong>.
*
* <p>Note that setting this attribute to {@code true} will affect <em>all</em>
* Spring-managed beans requiring proxying, not just those marked with {@code @Async}.
* For example, other beans marked with Spring's {@code @Transactional} annotation
@@ -176,4 +175,5 @@ public @interface EnableAsync {
* existing proxies rather than double-proxy.
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -23,13 +23,12 @@ import org.springframework.context.annotation.Role;
import org.springframework.scheduling.config.TaskManagementConfigUtils;
/**
* {@code @Configuration} class that registers a {@link
* ScheduledAnnotationBeanPostProcessor} bean capable of processing Spring's @{@link
* Scheduled} annotation.
* {@code @Configuration} class that registers a {@link ScheduledAnnotationBeanPostProcessor}
* bean capable of processing Spring's @{@link Scheduled} annotation.
*
* <p>This configuration class is automatically imported when using the @{@link
* EnableScheduling} annotation. See {@code @EnableScheduling} Javadoc for complete usage
* details.
* <p>This configuration class is automatically imported when using the
* @{@link EnableScheduling} annotation. See {@code @EnableScheduling}'s javadoc
* for complete usage details.
*
* @author Chris Beams
* @since 3.1

View File

@@ -543,7 +543,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
* Return the primary Validator to apply after each binding step, if any.
*/
public Validator getValidator() {
return this.validators.size() > 0 ? this.validators.get(0) : null;
return (this.validators.size() > 0 ? this.validators.get(0) : null);
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 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.
@@ -67,17 +67,6 @@ public class EnableAsyncTests {
asyncBean.work();
}
@Configuration
@EnableAsync
static class AsyncConfig {
@Bean
public AsyncBean asyncBean() {
return new AsyncBean();
}
}
@Test
public void withAsyncBeanWithExecutorQualifiedByName() throws ExecutionException, InterruptedException {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -95,49 +84,6 @@ public class EnableAsyncTests {
assertThat(workerThread3.get().getName(), startsWith("otherExecutor-"));
}
static class AsyncBeanWithExecutorQualifiedByName {
@Async
public Future<Thread> work0() {
return new AsyncResult<Thread>(Thread.currentThread());
}
@Async("e1")
public Future<Thread> work() {
return new AsyncResult<Thread>(Thread.currentThread());
}
@Async("otherExecutor")
public Future<Thread> work2() {
return new AsyncResult<Thread>(Thread.currentThread());
}
@Async("e2")
public Future<Thread> work3() {
return new AsyncResult<Thread>(Thread.currentThread());
}
}
static class AsyncBean {
private Thread threadOfExecution;
@Async
public void work() {
this.threadOfExecution = Thread.currentThread();
}
@Async
public void fail() {
throw new UnsupportedOperationException();
}
public Thread getThreadOfExecution() {
return threadOfExecution;
}
}
@Test
public void asyncProcessorIsOrderedLowestPrecedenceByDefault() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -148,7 +94,6 @@ public class EnableAsyncTests {
assertThat(bpp.getOrder(), is(Ordered.LOWEST_PRECEDENCE));
}
@Test
public void orderAttributeIsPropagated() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -159,17 +104,6 @@ public class EnableAsyncTests {
assertThat(bpp.getOrder(), is(Ordered.HIGHEST_PRECEDENCE));
}
@Configuration
@EnableAsync(order=Ordered.HIGHEST_PRECEDENCE)
static class OrderedAsyncConfig {
@Bean
public AsyncBean asyncBean() {
return new AsyncBean();
}
}
@Test
public void customAsyncAnnotationIsPropagated() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -188,51 +122,16 @@ public class EnableAsyncTests {
assertTrue("bean was not async advised as expected", isAsyncAdvised);
}
@Configuration
@EnableAsync(annotation=CustomAsync.class)
static class CustomAsyncAnnotationConfig {
@Bean
public CustomAsyncBean asyncBean() {
return new CustomAsyncBean();
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface CustomAsync {
}
static class CustomAsyncBean {
@CustomAsync
public void work() {
}
}
/**
* Fails with classpath errors on trying to classload AnnotationAsyncExecutionAspect
*/
@Test(expected=BeanDefinitionStoreException.class)
@Test(expected = BeanDefinitionStoreException.class)
public void aspectModeAspectJAttemptsToRegisterAsyncAspect() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AspectJAsyncAnnotationConfig.class);
ctx.refresh();
}
@Configuration
@EnableAsync(mode=AdviceMode.ASPECTJ)
static class AspectJAsyncAnnotationConfig {
@Bean
public AsyncBean asyncBean() {
return new AsyncBean();
}
}
@Test
public void customExecutorIsPropagated() throws InterruptedException {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -257,9 +156,112 @@ public class EnableAsyncTests {
}
static class AsyncBeanWithExecutorQualifiedByName {
@Async
public Future<Thread> work0() {
return new AsyncResult<Thread>(Thread.currentThread());
}
@Async("e1")
public Future<Thread> work() {
return new AsyncResult<Thread>(Thread.currentThread());
}
@Async("otherExecutor")
public Future<Thread> work2() {
return new AsyncResult<Thread>(Thread.currentThread());
}
@Async("e2")
public Future<Thread> work3() {
return new AsyncResult<Thread>(Thread.currentThread());
}
}
static class AsyncBean {
private Thread threadOfExecution;
@Async
public void work() {
this.threadOfExecution = Thread.currentThread();
}
@Async
public void fail() {
throw new UnsupportedOperationException();
}
public Thread getThreadOfExecution() {
return threadOfExecution;
}
}
@Configuration
@EnableAsync(annotation = CustomAsync.class)
static class CustomAsyncAnnotationConfig {
@Bean
public CustomAsyncBean asyncBean() {
return new CustomAsyncBean();
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface CustomAsync {
}
static class CustomAsyncBean {
@CustomAsync
public void work() {
}
}
@Configuration
@EnableAsync(order = Ordered.HIGHEST_PRECEDENCE)
static class OrderedAsyncConfig {
@Bean
public AsyncBean asyncBean() {
return new AsyncBean();
}
}
@Configuration
@EnableAsync(mode = AdviceMode.ASPECTJ)
static class AspectJAsyncAnnotationConfig {
@Bean
public AsyncBean asyncBean() {
return new AsyncBean();
}
}
@Configuration
@EnableAsync
static class AsyncConfig {
@Bean
public AsyncBean asyncBean() {
return new AsyncBean();
}
}
@Configuration
@EnableAsync
static class CustomExecutorAsyncConfig implements AsyncConfigurer {
@Bean
public AsyncBean asyncBean() {
return new AsyncBean();
@@ -275,7 +277,7 @@ public class EnableAsyncTests {
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return exceptionHandler();
return exceptionHandler();
}
@Bean
@@ -288,6 +290,7 @@ public class EnableAsyncTests {
@Configuration
@EnableAsync
static class AsyncWithExecutorQualifiedByNameConfig {
@Bean
public AsyncBeanWithExecutorQualifiedByName asyncBean() {
return new AsyncBeanWithExecutorQualifiedByName();
@@ -295,15 +298,14 @@ public class EnableAsyncTests {
@Bean
public Executor e1() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
return executor;
return new ThreadPoolTaskExecutor();
}
@Bean
@Qualifier("e2")
public Executor otherExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
return executor;
return new ThreadPoolTaskExecutor();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2015 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.
@@ -41,6 +41,7 @@ import static org.junit.Assert.*;
* Tests use of @EnableScheduling on @Configuration classes.
*
* @author Chris Beams
* @author Sam Brannen
* @since 3.1
*/
public class EnableSchedulingTests {
@@ -50,6 +51,7 @@ public class EnableSchedulingTests {
Assume.group(TestGroup.PERFORMANCE);
}
@Test
public void withFixedRateTask() throws InterruptedException {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -138,12 +140,17 @@ public class EnableSchedulingTests {
ctx.register(AmbiguousExplicitSchedulerConfig.class);
try {
ctx.refresh();
} catch (IllegalStateException ex) {
}
catch (IllegalStateException ex) {
assertThat(ex.getMessage(), startsWith("More than one TaskScheduler"));
throw ex;
}
finally {
ctx.close();
}
}
@EnableScheduling @Configuration
static class AmbiguousExplicitSchedulerConfig {
@@ -236,6 +243,7 @@ public class EnableSchedulingTests {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(SchedulingEnabled_withAmbiguousTaskSchedulers_butNoActualTasks.class);
ctx.refresh();
ctx.close();
}
@@ -265,10 +273,14 @@ public class EnableSchedulingTests {
ctx.register(SchedulingEnabled_withAmbiguousTaskSchedulers_andSingleTask.class);
try {
ctx.refresh();
} catch (IllegalStateException ex) {
assertThat(ex.getMessage(), startsWith("More than one TaskScheduler and/or"));
}
catch (IllegalStateException ex) {
assertThat(ex.getMessage(), startsWith("More than one TaskScheduler"));
throw ex;
}
finally {
ctx.close();
}
}
@@ -295,6 +307,7 @@ public class EnableSchedulingTests {
}
}
@Test
public void withAmbiguousTaskSchedulers_andSingleTask_disambiguatedByScheduledTaskRegistrarBean() throws InterruptedException {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -476,6 +489,7 @@ public class EnableSchedulingTests {
}
}
@Test
public void withInitiallyDelayedFixedRateTask() throws InterruptedException {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
@@ -486,8 +500,8 @@ public class EnableSchedulingTests {
AtomicInteger counter = ctx.getBean(AtomicInteger.class);
ctx.close();
assertThat(counter.get(), greaterThan(0)); // the @Scheduled method was called
assertThat(counter.get(), lessThanOrEqualTo(10)); // but not more than times the delay allows
assertThat(counter.get(), greaterThan(0)); // the @Scheduled method was called
assertThat(counter.get(), lessThanOrEqualTo(10)); // but not more than times the delay allows
}