From 46eba3dbfad310bbafbf0a1002a386246288df1c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 19 Jul 2017 22:22:14 +0200 Subject: [PATCH] Nullability fine-tuning around declaration inconsistencies Issue: SPR-15720 Issue: SPR-15792 --- .../java/org/springframework/aop/Advisor.java | 9 ++++ .../aop/aspectj/AspectJPointcutAdvisor.java | 7 ++-- .../config/AdvisorComponentDefinition.java | 10 ++--- ...BeanFactoryAwareAspectInstanceFactory.java | 15 ++++--- .../AbstractAdvisingBeanPostProcessor.java | 9 +++- .../aop/framework/AdvisedSupport.java | 11 +---- .../AbstractAdvisorAutoProxyCreator.java | 3 ++ .../autoproxy/AbstractAutoProxyCreator.java | 31 +++++++------- .../autoproxy/BeanNameAutoProxyCreator.java | 4 +- ...InfrastructureAdvisorAutoProxyCreator.java | 6 ++- .../support/AbstractExpressionPointcut.java | 1 + .../AbstractGenericPointcutAdvisor.java | 7 ++-- .../DelegatingIntroductionInterceptor.java | 1 + .../StaticMethodMatcherPointcutAdvisor.java | 4 +- .../AbstractNestablePropertyAccessor.java | 1 + .../beans/BeanInstantiationException.java | 2 + .../beans/DirectFieldAccessor.java | 3 +- .../beans/TypeConverterSupport.java | 5 ++- .../NoUniqueBeanDefinitionException.java | 3 +- .../AnnotatedGenericBeanDefinition.java | 5 ++- .../RequiredAnnotationBeanPostProcessor.java | 1 + .../factory/config/PropertiesFactoryBean.java | 4 +- .../parsing/BeanComponentDefinition.java | 25 ++++------- .../support/BeanDefinitionBuilder.java | 28 +++++-------- .../DefaultBeanDefinitionDocumentReader.java | 6 ++- .../commonj/ScheduledTimerListener.java | 8 +++- .../FreeMarkerConfigurationFactoryBean.java | 4 +- .../concurrent/ConcurrentMapCacheManager.java | 3 +- .../interceptor/AbstractCacheInvoker.java | 2 +- .../interceptor/AbstractCacheResolver.java | 10 +++-- ...eanFactoryCacheOperationSourceAdvisor.java | 4 +- .../cache/interceptor/CachePutOperation.java | 7 +++- .../cache/interceptor/CacheableOperation.java | 7 +++- .../cache/interceptor/NamedCacheResolver.java | 3 +- .../interceptor/SimpleCacheErrorHandler.java | 5 ++- .../cache/support/SimpleCacheManager.java | 5 ++- .../annotation/ConfigurationClass.java | 12 +++--- .../event/EventListenerMethodProcessor.java | 30 +++++++------ .../support/ApplicationListenerDetector.java | 10 ++--- .../ClassPathXmlApplicationContext.java | 2 + .../support/ConversionServiceFactoryBean.java | 5 ++- .../support/DefaultLifecycleProcessor.java | 24 +++++++---- .../weaving/AspectJWeavingEnabler.java | 4 +- .../joda/DateTimeFormatterFactoryBean.java | 4 +- .../DateTimeFormatterFactoryBean.java | 4 +- .../assembler/MetadataMBeanInfoAssembler.java | 6 ++- .../jmx/export/metadata/ManagedAttribute.java | 12 ++++-- .../jmx/export/metadata/ManagedMetric.java | 17 ++++++-- .../jmx/export/metadata/ManagedResource.java | 24 ++++++++--- .../jndi/TypeMismatchNamingException.java | 14 ++----- .../support/RemoteInvocationResult.java | 7 ++-- .../concurrent/ConcurrentTaskExecutor.java | 37 ++++++++-------- .../concurrent/ForkJoinPoolFactoryBean.java | 25 ++++++----- .../concurrent/ScheduledExecutorTask.java | 3 ++ .../support/SimpleTriggerContext.java | 6 ++- .../scripting/ScriptCompilationException.java | 3 +- .../scripting/bsh/BshScriptEvaluator.java | 3 +- .../springframework/ui/ExtendedModelMap.java | 8 ++-- .../MethodValidationPostProcessor.java | 1 + .../aop/config/AopNamespaceHandlerTests.java | 30 ++++++++++--- .../core/ReactiveAdapterRegistry.java | 7 +--- .../AnnotationAttributesReadingVisitor.java | 11 ++--- .../util/xml/StaxEventXMLReader.java | 4 +- .../springframework/util/xml/StaxResult.java | 24 ++++++----- .../springframework/util/xml/StaxSource.java | 26 ++++++------ .../util/xml/StaxStreamXMLReader.java | 4 +- .../spel/ast/CompoundExpression.java | 5 ++- .../spel/ast/OperatorInstanceof.java | 16 ++++--- .../expression/spel/ast/TypeReference.java | 7 +++- .../expression/spel/ast/ValueRef.java | 4 +- .../support/StandardEvaluationContext.java | 1 + .../jdbc/InvalidResultSetAccessException.java | 5 ++- .../jdbc/core/JdbcTemplate.java | 1 + .../jdbc/core/RowCountCallbackHandler.java | 15 ++++--- .../metadata/GenericCallMetaDataProvider.java | 2 +- .../jdbc/core/simple/AbstractJdbcCall.java | 6 ++- .../jdbc/core/simple/AbstractJdbcInsert.java | 6 ++- .../support/JdbcBeanDefinitionReader.java | 2 + .../IsolationLevelDataSourceAdapter.java | 2 +- .../datasource/SimpleDriverDataSource.java | 7 +++- .../WebSphereDataSourceAdapter.java | 2 +- .../init/DataSourceInitializer.java | 2 + .../jdbc/support/xml/Jdbc4SqlXmlHandler.java | 13 +++--- .../AbstractMessageListenerContainer.java | 5 ++- .../adapter/MessageListenerAdapter.java | 6 ++- .../MessagingMessageListenerAdapter.java | 23 ++++++---- .../endpoint/JmsMessageEndpointFactory.java | 14 +++---- .../remoting/JmsInvokerServiceExporter.java | 1 + .../MarshallingMessageConverter.java | 14 ++++--- .../converter/DefaultContentTypeResolver.java | 4 +- .../core/GenericMessagingTemplate.java | 1 + .../broker/AbstractBrokerMessageHandler.java | 4 +- .../simp/stomp/DefaultStompSession.java | 1 + .../simp/stomp/StompHeaderAccessor.java | 4 +- .../simp/user/MultiServerUserRegistry.java | 30 ++++++++----- .../messaging/simp/user/SimpSession.java | 4 +- .../messaging/simp/user/SimpSubscription.java | 8 ++-- .../support/ChannelInterceptorAdapter.java | 7 ++-- .../user/MultiServerUserRegistryTests.java | 12 ++---- .../support/OpenSessionInViewInterceptor.java | 25 +++++++---- .../jpa/AbstractEntityManagerFactoryBean.java | 12 ++++-- .../orm/jpa/DefaultJpaDialect.java | 4 +- ...ocalContainerEntityManagerFactoryBean.java | 7 +++- .../SpringPersistenceUnitInfo.java | 1 + .../orm/jpa/vendor/HibernateJpaDialect.java | 2 +- .../reactive/MockServerHttpRequest.java | 12 +++--- .../mock/web/MockSessionCookieConfig.java | 18 ++++++-- .../AbstractJUnit4SpringContextTests.java | 4 +- ...TransactionalJUnit4SpringContextTests.java | 7 +++- .../AbstractTestContextBootstrapper.java | 8 +--- ...TransactionalTestNGSpringContextTests.java | 6 ++- .../web/WebMergedContextConfiguration.java | 2 +- .../web/client/DefaultRequestExpectation.java | 3 +- .../WebConnectionHtmlUnitDriver.java | 11 +++-- .../result/JsonPathResultMatchers.java | 2 + .../spr/RequestContextHolderTests.java | 2 + ...onnectionSpecConnectionFactoryAdapter.java | 1 + .../jca/cci/core/support/CommAreaRecord.java | 16 +++---- .../context/SpringContextResourceAdapter.java | 5 ++- .../GenericMessageEndpointFactory.java | 18 ++++++-- ...toryTransactionAttributeSourceAdvisor.java | 4 +- .../DefaultTransactionAttribute.java | 3 +- .../support/DefaultTransactionDefinition.java | 1 + .../springframework/http/ResponseCookie.java | 8 +++- .../client/support/AsyncHttpAccessor.java | 10 ++++- .../http/client/support/ProxyFactoryBean.java | 11 +++-- .../http/codec/xml/Jaxb2XmlDecoder.java | 1 + .../json/GsonHttpMessageConverter.java | 5 ++- .../json/JsonbHttpMessageConverter.java | 5 ++- .../reactive/AbstractServerHttpRequest.java | 2 +- .../caucho/HessianProxyFactoryBean.java | 4 +- .../AbstractHttpInvokerRequestExecutor.java | 2 + .../HttpInvokerProxyFactoryBean.java | 2 + .../jaxws/JaxWsPortProxyFactoryBean.java | 2 + .../web/HttpSessionRequiredException.java | 3 +- .../bind/support/SessionAttributeStore.java | 4 +- .../ExtractingResponseErrorHandler.java | 36 +++++++--------- .../support/HttpRequestHandlerServlet.java | 7 +++- .../context/support/LiveBeansViewServlet.java | 12 +++++- .../ServletContextAttributeExporter.java | 24 ++++++----- .../jsf/DelegatingNavigationHandlerProxy.java | 4 +- .../web/method/HandlerMethod.java | 3 ++ .../method/annotation/MapMethodProcessor.java | 15 ++++--- .../web/method/annotation/ModelFactory.java | 9 ++-- .../annotation/ModelMethodProcessor.java | 6 ++- .../annotation/SessionAttributesHandler.java | 13 +++--- .../SessionStatusMethodArgumentResolver.java | 9 ++-- .../server/adapter/WebHttpHandlerBuilder.java | 27 ++++++------ ...ttpInvokerFactoryBeanIntegrationTests.java | 17 ++------ .../ExtractingResponseErrorHandlerTests.java | 12 +++--- .../request/RequestScopedProxyTests.java | 2 +- .../web/reactive/DispatcherHandler.java | 7 ++-- .../reactive/config/PathMatchConfigurer.java | 3 ++ .../DefaultHandlerStrategiesBuilder.java | 11 +++-- .../resource/PathResourceResolver.java | 4 +- .../view/script/ScriptTemplateConfigurer.java | 39 ++++++++++++----- .../view/script/ScriptTemplateView.java | 2 +- .../web/servlet/AsyncHandlerInterceptor.java | 5 +-- .../web/servlet/HandlerInterceptor.java | 10 ++--- .../AnnotationDrivenBeanDefinitionParser.java | 4 ++ .../annotation/AsyncSupportConfigurer.java | 2 + .../annotation/PathMatchConfigurer.java | 8 +++- .../handler/HandlerInterceptorAdapter.java | 17 ++++---- .../servlet/handler/MappedInterceptor.java | 42 ++++++++++--------- .../WebRequestHandlerInterceptorAdapter.java | 10 ++--- .../i18n/AbstractLocaleContextResolver.java | 2 +- .../i18n/AcceptHeaderLocaleResolver.java | 2 +- .../servlet/i18n/LocaleChangeInterceptor.java | 6 +-- .../servlet/mvc/WebContentInterceptor.java | 11 ++--- .../AbstractNameValueExpression.java | 1 + ...eferredResultMethodReturnValueHandler.java | 2 +- .../DefaultServletHttpRequestHandler.java | 7 +++- .../servlet/resource/TransformedResource.java | 1 + .../web/servlet/tags/EscapeBodyTag.java | 7 +++- .../web/servlet/view/AbstractView.java | 1 + .../view/script/ScriptTemplateConfigurer.java | 38 +++++++++++++---- .../standard/StandardWebSocketSession.java | 2 + .../WebSocketTransportRegistration.java | 7 +++- .../messaging/DefaultSimpUserRegistry.java | 16 +++---- .../messaging/WebSocketStompClient.java | 24 +++++++---- .../HttpSessionHandshakeInterceptor.java | 4 +- .../support/OriginHandshakeInterceptor.java | 5 ++- .../client/DefaultTransportRequest.java | 1 + .../sockjs/client/WebSocketTransport.java | 3 +- .../handler/AbstractTransportHandler.java | 6 ++- .../session/AbstractHttpSockJsSession.java | 6 ++- 186 files changed, 986 insertions(+), 619 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/Advisor.java b/spring-aop/src/main/java/org/springframework/aop/Advisor.java index a06d9809dcf..2370d032f46 100644 --- a/spring-aop/src/main/java/org/springframework/aop/Advisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/Advisor.java @@ -31,9 +31,18 @@ import org.aopalliance.aop.Advice; * implemented using interception. * * @author Rod Johnson + * @author Juergen Hoeller */ public interface Advisor { + /** + * Common placeholder for an empty {@code Advice} to be returned from + * {@link #getAdvice()} if no proper advice has been configured (yet). + * @since 5.0 + */ + Advice EMPTY_ADVICE = new Advice() {}; + + /** * Return the advice part of this aspect. An advice may be an * interceptor, a before advice, a throws advice, etc. diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java index 5a534e0f6af..7160354b800 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJPointcutAdvisor.java @@ -23,7 +23,6 @@ import org.springframework.aop.PointcutAdvisor; import org.springframework.core.Ordered; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; /** * AspectJPointcutAdvisor that adapts an {@link AbstractAspectJAdvice} @@ -53,11 +52,11 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered { this.pointcut = advice.buildSafePointcut(); } + public void setOrder(int order) { this.order = order; } - @Override public boolean isPerInstance() { return true; @@ -93,12 +92,12 @@ public class AspectJPointcutAdvisor implements PointcutAdvisor, Ordered { return false; } AspectJPointcutAdvisor otherAdvisor = (AspectJPointcutAdvisor) other; - return (ObjectUtils.nullSafeEquals(this.advice, otherAdvisor.advice)); + return this.advice.equals(otherAdvisor.advice); } @Override public int hashCode() { - return AspectJPointcutAdvisor.class.hashCode(); + return AspectJPointcutAdvisor.class.hashCode() * 29 + this.advice.hashCode(); } } diff --git a/spring-aop/src/main/java/org/springframework/aop/config/AdvisorComponentDefinition.java b/spring-aop/src/main/java/org/springframework/aop/config/AdvisorComponentDefinition.java index 0d71063bd5f..44d9f34c4b3 100644 --- a/spring-aop/src/main/java/org/springframework/aop/config/AdvisorComponentDefinition.java +++ b/spring-aop/src/main/java/org/springframework/aop/config/AdvisorComponentDefinition.java @@ -39,11 +39,11 @@ public class AdvisorComponentDefinition extends AbstractComponentDefinition { private final BeanDefinition advisorDefinition; - private String description; + private final String description; - private BeanReference[] beanReferences; + private final BeanReference[] beanReferences; - private BeanDefinition[] beanDefinitions; + private final BeanDefinition[] beanDefinitions; public AdvisorComponentDefinition(String advisorBeanName, BeanDefinition advisorDefinition) { @@ -57,11 +57,7 @@ public class AdvisorComponentDefinition extends AbstractComponentDefinition { Assert.notNull(advisorDefinition, "'advisorDefinition' must not be null"); this.advisorBeanName = advisorBeanName; this.advisorDefinition = advisorDefinition; - unwrapDefinitions(advisorDefinition, pointcutDefinition); - } - - private void unwrapDefinitions(BeanDefinition advisorDefinition, @Nullable BeanDefinition pointcutDefinition) { MutablePropertyValues pvs = advisorDefinition.getPropertyValues(); BeanReference adviceReference = (BeanReference) pvs.get("adviceBeanName"); Assert.state(adviceReference != null, "Missing 'adviceBeanName' property"); diff --git a/spring-aop/src/main/java/org/springframework/aop/config/SimpleBeanFactoryAwareAspectInstanceFactory.java b/spring-aop/src/main/java/org/springframework/aop/config/SimpleBeanFactoryAwareAspectInstanceFactory.java index 64cc673bab7..39a08aa5901 100644 --- a/spring-aop/src/main/java/org/springframework/aop/config/SimpleBeanFactoryAwareAspectInstanceFactory.java +++ b/spring-aop/src/main/java/org/springframework/aop/config/SimpleBeanFactoryAwareAspectInstanceFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -21,6 +21,8 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.core.Ordered; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -34,8 +36,10 @@ import org.springframework.util.StringUtils; */ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstanceFactory, BeanFactoryAware { + @Nullable private String aspectBeanName; + @Nullable private BeanFactory beanFactory; @@ -50,9 +54,7 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; - if (!StringUtils.hasText(this.aspectBeanName)) { - throw new IllegalArgumentException("'aspectBeanName' is required"); - } + Assert.notNull(this.aspectBeanName, "'aspectBeanName' is required"); } @@ -62,6 +64,8 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan */ @Override public Object getAspectInstance() { + Assert.state(this.beanFactory != null, "No BeanFactory set"); + Assert.state(this.aspectBeanName != null, "No 'aspectBeanName' set"); return this.beanFactory.getBean(this.aspectBeanName); } @@ -77,7 +81,8 @@ public class SimpleBeanFactoryAwareAspectInstanceFactory implements AspectInstan @Override public int getOrder() { - if (this.beanFactory.isSingleton(this.aspectBeanName) && + if (this.beanFactory != null && this.aspectBeanName != null && + this.beanFactory.isSingleton(this.aspectBeanName) && this.beanFactory.isTypeMatch(this.aspectBeanName, Ordered.class)) { return ((Ordered) this.beanFactory.getBean(this.aspectBeanName)).getOrder(); } diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java b/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java index c267feca14a..4faca7ce2d4 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -22,6 +22,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.springframework.aop.Advisor; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.lang.Nullable; /** * Base class for {@link BeanPostProcessor} implementations that apply a @@ -33,6 +34,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor; @SuppressWarnings("serial") public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSupport implements BeanPostProcessor { + @Nullable protected Advisor advisor; protected boolean beforeExistingAdvisors = false; @@ -61,7 +63,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu @Override public Object postProcessAfterInitialization(Object bean, String beanName) { - if (bean instanceof AopInfrastructureBean) { + if (bean instanceof AopInfrastructureBean || this.advisor == null) { // Ignore AOP infrastructure such as scoped proxies. return bean; } @@ -125,6 +127,9 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSu if (eligible != null) { return eligible; } + if (this.advisor == null) { + return false; + } eligible = AopUtils.canApply(this.advisor, targetClass); this.eligibleBeans.put(targetClass, eligible); return eligible; diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java index efa0e1e8b5a..e66e32daeeb 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java @@ -107,7 +107,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised { * No-arg constructor for use as a JavaBean. */ public AdvisedSupport() { - initMethodCache(); + this.methodCache = new ConcurrentHashMap<>(32); } /** @@ -119,13 +119,6 @@ public class AdvisedSupport extends ProxyConfig implements Advised { setInterfaces(interfaces); } - /** - * Initialize the method cache. - */ - private void initMethodCache() { - this.methodCache = new ConcurrentHashMap<>(32); - } - /** * Set the given object as target. @@ -558,7 +551,7 @@ public class AdvisedSupport extends ProxyConfig implements Advised { ois.defaultReadObject(); // Initialize transient fields. - initMethodCache(); + this.methodCache = new ConcurrentHashMap<>(32); } diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java index adc50355f49..ce471d51d89 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAdvisorAutoProxyCreator.java @@ -25,6 +25,7 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Generic auto proxy creator that builds AOP proxies for specific beans @@ -48,6 +49,7 @@ import org.springframework.lang.Nullable; @SuppressWarnings("serial") public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator { + @Nullable private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper; @@ -101,6 +103,7 @@ public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyC * @return the List of candidate Advisors */ protected List findCandidateAdvisors() { + Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); return this.advisorRetrievalHelper.findAdvisorBeans(); } diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java index 0d2d69afe0e..81b4714d3a8 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java @@ -203,7 +203,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport } @Override - public void setBeanFactory(@Nullable BeanFactory beanFactory) { + public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } @@ -241,10 +241,10 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport } @Override - public Object postProcessBeforeInstantiation(Class beanClass, @Nullable String beanName) throws BeansException { + public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { Object cacheKey = getCacheKey(beanClass, beanName); - if (beanName == null || !this.targetSourcedBeans.contains(beanName)) { + if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { return null; } @@ -257,15 +257,15 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport // Create proxy here if we have a custom TargetSource. // Suppresses unnecessary default instantiation of the target bean: // The TargetSource will handle target instances in a custom fashion. - if (beanName != null) { - TargetSource targetSource = getCustomTargetSource(beanClass, beanName); - if (targetSource != null) { + TargetSource targetSource = getCustomTargetSource(beanClass, beanName); + if (targetSource != null) { + if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); - Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); - Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); - this.proxyTypes.put(cacheKey, proxy.getClass()); - return proxy; } + Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); + Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); + this.proxyTypes.put(cacheKey, proxy.getClass()); + return proxy; } return null; @@ -333,8 +333,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport * @param cacheKey the cache key for metadata access * @return a proxy wrapping the bean, or the raw bean instance as-is */ - protected Object wrapIfNecessary(Object bean, @Nullable String beanName, Object cacheKey) { - if (beanName != null && this.targetSourcedBeans.contains(beanName)) { + protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { + if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { @@ -391,7 +391,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport * @param beanName the name of the bean * @return whether to skip the given bean */ - protected boolean shouldSkip(Class beanClass, @Nullable String beanName) { + protected boolean shouldSkip(Class beanClass, String beanName) { return false; } @@ -582,8 +582,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport * @see #PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS */ @Nullable - protected abstract Object[] getAdvicesAndAdvisorsForBean(Class beanClass, - @Nullable String beanName, @Nullable TargetSource customTargetSource) - throws BeansException; + protected abstract Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, + @Nullable TargetSource customTargetSource) throws BeansException; } diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/BeanNameAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/BeanNameAutoProxyCreator.java index 5fef0074338..b6bce882afc 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/BeanNameAutoProxyCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/BeanNameAutoProxyCreator.java @@ -76,7 +76,9 @@ public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator { */ @Override @Nullable - protected Object[] getAdvicesAndAdvisorsForBean(Class beanClass, String beanName, @Nullable TargetSource targetSource) { + protected Object[] getAdvicesAndAdvisorsForBean( + Class beanClass, String beanName, @Nullable TargetSource targetSource) { + if (this.beanNames != null) { for (String mappedName : this.beanNames) { if (FactoryBean.class.isAssignableFrom(beanClass)) { diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/InfrastructureAdvisorAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/InfrastructureAdvisorAutoProxyCreator.java index 90034eafbba..5d4c555a1f5 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/InfrastructureAdvisorAutoProxyCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/InfrastructureAdvisorAutoProxyCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -18,6 +18,7 @@ package org.springframework.aop.framework.autoproxy; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.lang.Nullable; /** * Auto-proxy creator that considers infrastructure Advisor beans only, @@ -29,6 +30,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; @SuppressWarnings("serial") public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator { + @Nullable private ConfigurableListableBeanFactory beanFactory; @@ -40,7 +42,7 @@ public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoPr @Override protected boolean isEligibleAdvisorBean(String beanName) { - return (this.beanFactory.containsBeanDefinition(beanName) && + return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) && this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE); } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AbstractExpressionPointcut.java b/spring-aop/src/main/java/org/springframework/aop/support/AbstractExpressionPointcut.java index 6112d402818..2555c4cf109 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AbstractExpressionPointcut.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AbstractExpressionPointcut.java @@ -89,6 +89,7 @@ public abstract class AbstractExpressionPointcut implements ExpressionPointcut, * Return this pointcut's expression. */ @Override + @Nullable public String getExpression() { return this.expression; } diff --git a/spring-aop/src/main/java/org/springframework/aop/support/AbstractGenericPointcutAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/support/AbstractGenericPointcutAdvisor.java index f3a9137b15b..a13444e72ce 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/AbstractGenericPointcutAdvisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/AbstractGenericPointcutAdvisor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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,7 +19,8 @@ package org.springframework.aop.support; import org.aopalliance.aop.Advice; /** - * Abstract generic PointcutAdvisor that allows for any Advice to be configured. + * Abstract generic {@link org.springframework.aop.PointcutAdvisor} + * that allows for any {@link Advice} to be configured. * * @author Juergen Hoeller * @since 2.0 @@ -29,7 +30,7 @@ import org.aopalliance.aop.Advice; @SuppressWarnings("serial") public abstract class AbstractGenericPointcutAdvisor extends AbstractPointcutAdvisor { - private Advice advice; + private Advice advice = EMPTY_ADVICE; /** diff --git a/spring-aop/src/main/java/org/springframework/aop/support/DelegatingIntroductionInterceptor.java b/spring-aop/src/main/java/org/springframework/aop/support/DelegatingIntroductionInterceptor.java index 8f9abf16470..fb6cd155154 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/DelegatingIntroductionInterceptor.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/DelegatingIntroductionInterceptor.java @@ -57,6 +57,7 @@ public class DelegatingIntroductionInterceptor extends IntroductionInfoSupport * Object that actually implements the interfaces. * May be "this" if a subclass implements the introduced interfaces. */ + @Nullable private Object delegate; diff --git a/spring-aop/src/main/java/org/springframework/aop/support/StaticMethodMatcherPointcutAdvisor.java b/spring-aop/src/main/java/org/springframework/aop/support/StaticMethodMatcherPointcutAdvisor.java index 9dbe10dbf4f..ecbc42397b5 100644 --- a/spring-aop/src/main/java/org/springframework/aop/support/StaticMethodMatcherPointcutAdvisor.java +++ b/spring-aop/src/main/java/org/springframework/aop/support/StaticMethodMatcherPointcutAdvisor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -38,7 +38,7 @@ public abstract class StaticMethodMatcherPointcutAdvisor extends StaticMethodMat private int order = Integer.MAX_VALUE; - private Advice advice; + private Advice advice = EMPTY_ADVICE; /** diff --git a/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java b/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java index fd0c7501a43..5ab67b7558e 100644 --- a/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/AbstractNestablePropertyAccessor.java @@ -578,6 +578,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA @Nullable Object newValue, @Nullable Class requiredType, @Nullable TypeDescriptor td) throws TypeMismatchException { + Assert.state(this.typeConverterDelegate != null, "No TypeConverterDelegate"); try { return this.typeConverterDelegate.convertIfNecessary(propertyName, oldValue, newValue, requiredType, td); } diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java b/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java index d4f9b7d3bf7..4f11119f588 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java @@ -33,8 +33,10 @@ public class BeanInstantiationException extends FatalBeanException { private Class beanClass; + @Nullable private Constructor constructor; + @Nullable private Method constructingMethod; diff --git a/spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java b/spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java index fe2c1863e43..912f32e0775 100644 --- a/spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/DirectFieldAccessor.java @@ -22,6 +22,7 @@ import java.util.Map; import org.springframework.core.ResolvableType; import org.springframework.core.convert.TypeDescriptor; +import org.springframework.lang.Nullable; import org.springframework.util.ReflectionUtils; /** @@ -134,7 +135,7 @@ public class DirectFieldAccessor extends AbstractNestablePropertyAccessor { } @Override - public void setValue(Object value) throws Exception { + public void setValue(@Nullable Object value) throws Exception { try { ReflectionUtils.makeAccessible(this.field); this.field.set(getWrappedInstance(), value); diff --git a/spring-beans/src/main/java/org/springframework/beans/TypeConverterSupport.java b/spring-beans/src/main/java/org/springframework/beans/TypeConverterSupport.java index b73832453fe..9c875389618 100644 --- a/spring-beans/src/main/java/org/springframework/beans/TypeConverterSupport.java +++ b/spring-beans/src/main/java/org/springframework/beans/TypeConverterSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -22,6 +22,7 @@ import org.springframework.core.MethodParameter; import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Base implementation of the {@link TypeConverter} interface, using a package-private delegate. @@ -33,6 +34,7 @@ import org.springframework.lang.Nullable; */ public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport implements TypeConverter { + @Nullable TypeConverterDelegate typeConverterDelegate; @@ -59,6 +61,7 @@ public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport private T doConvert(@Nullable Object value,@Nullable Class requiredType, @Nullable MethodParameter methodParam, @Nullable Field field) throws TypeMismatchException { + Assert.state(this.typeConverterDelegate != null, "No TypeConverterDelegate"); try { if (field != null) { return this.typeConverterDelegate.convertIfNecessary(value, requiredType, field); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/NoUniqueBeanDefinitionException.java b/spring-beans/src/main/java/org/springframework/beans/factory/NoUniqueBeanDefinitionException.java index 02617c8fe99..1652dce7ebc 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/NoUniqueBeanDefinitionException.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/NoUniqueBeanDefinitionException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -35,6 +35,7 @@ public class NoUniqueBeanDefinitionException extends NoSuchBeanDefinitionExcepti private int numberOfBeansFound; + @Nullable private Collection beanNamesFound; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AnnotatedGenericBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AnnotatedGenericBeanDefinition.java index 559145268b3..e34f27741f0 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AnnotatedGenericBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AnnotatedGenericBeanDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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 org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.MethodMetadata; import org.springframework.core.type.StandardAnnotationMetadata; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -44,6 +45,7 @@ public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implem private final AnnotationMetadata metadata; + @Nullable private MethodMetadata factoryMethodMetadata; @@ -98,6 +100,7 @@ public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implem } @Override + @Nullable public final MethodMetadata getFactoryMethodMetadata() { return this.factoryMethodMetadata; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java index 3df0f5178de..4b1937b0d5c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java @@ -89,6 +89,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP private int order = Ordered.LOWEST_PRECEDENCE - 1; + @Nullable private ConfigurableListableBeanFactory beanFactory; /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertiesFactoryBean.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertiesFactoryBean.java index adc415d0d57..17fbc9c4edf 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertiesFactoryBean.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertiesFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -22,6 +22,7 @@ import java.util.Properties; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.support.PropertiesLoaderSupport; +import org.springframework.lang.Nullable; /** * Allows for making a properties file from a classpath location available @@ -47,6 +48,7 @@ public class PropertiesFactoryBean extends PropertiesLoaderSupport private boolean singleton = true; + @Nullable private Properties singletonInstance; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/parsing/BeanComponentDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/parsing/BeanComponentDefinition.java index c5b1c54a398..c51bf4c6e1c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/parsing/BeanComponentDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/parsing/BeanComponentDefinition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -47,8 +47,7 @@ public class BeanComponentDefinition extends BeanDefinitionHolder implements Com * @param beanName the name of the bean */ public BeanComponentDefinition(BeanDefinition beanDefinition, String beanName) { - super(beanDefinition, beanName); - findInnerBeanDefinitionsAndBeanReferences(beanDefinition); + this(new BeanDefinitionHolder(beanDefinition, beanName)); } /** @@ -58,27 +57,21 @@ public class BeanComponentDefinition extends BeanDefinitionHolder implements Com * @param aliases alias names for the bean, or {@code null} if none */ public BeanComponentDefinition(BeanDefinition beanDefinition, String beanName, @Nullable String[] aliases) { - super(beanDefinition, beanName, aliases); - findInnerBeanDefinitionsAndBeanReferences(beanDefinition); + this(new BeanDefinitionHolder(beanDefinition, beanName, aliases)); } /** * Create a new BeanComponentDefinition for the given bean. - * @param holder the BeanDefinitionHolder encapsulating the - * bean definition as well as the name of the bean + * @param beanDefinitionHolder the BeanDefinitionHolder encapsulating + * the bean definition as well as the name of the bean */ - public BeanComponentDefinition(BeanDefinitionHolder holder) { - super(holder); - findInnerBeanDefinitionsAndBeanReferences(holder.getBeanDefinition()); - } + public BeanComponentDefinition(BeanDefinitionHolder beanDefinitionHolder) { + super(beanDefinitionHolder); - - private void findInnerBeanDefinitionsAndBeanReferences(BeanDefinition beanDefinition) { List innerBeans = new ArrayList<>(); List references = new ArrayList<>(); - PropertyValues propertyValues = beanDefinition.getPropertyValues(); - for (int i = 0; i < propertyValues.getPropertyValues().length; i++) { - PropertyValue propertyValue = propertyValues.getPropertyValues()[i]; + PropertyValues propertyValues = beanDefinitionHolder.getBeanDefinition().getPropertyValues(); + for (PropertyValue propertyValue : propertyValues.getPropertyValues()) { Object value = propertyValue.getValue(); if (value instanceof BeanDefinitionHolder) { innerBeans.add(((BeanDefinitionHolder) value).getBeanDefinition()); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java index 75b37718ecd..c5916ab8ece 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/BeanDefinitionBuilder.java @@ -40,9 +40,7 @@ public class BeanDefinitionBuilder { * Create a new {@code BeanDefinitionBuilder} used to construct a {@link GenericBeanDefinition}. */ public static BeanDefinitionBuilder genericBeanDefinition() { - BeanDefinitionBuilder builder = new BeanDefinitionBuilder(); - builder.beanDefinition = new GenericBeanDefinition(); - return builder; + return new BeanDefinitionBuilder(new GenericBeanDefinition()); } /** @@ -50,8 +48,7 @@ public class BeanDefinitionBuilder { * @param beanClassName the class name for the bean that the definition is being created for */ public static BeanDefinitionBuilder genericBeanDefinition(String beanClassName) { - BeanDefinitionBuilder builder = new BeanDefinitionBuilder(); - builder.beanDefinition = new GenericBeanDefinition(); + BeanDefinitionBuilder builder = new BeanDefinitionBuilder(new GenericBeanDefinition()); builder.beanDefinition.setBeanClassName(beanClassName); return builder; } @@ -61,8 +58,7 @@ public class BeanDefinitionBuilder { * @param beanClass the {@code Class} of the bean that the definition is being created for */ public static BeanDefinitionBuilder genericBeanDefinition(Class beanClass) { - BeanDefinitionBuilder builder = new BeanDefinitionBuilder(); - builder.beanDefinition = new GenericBeanDefinition(); + BeanDefinitionBuilder builder = new BeanDefinitionBuilder(new GenericBeanDefinition()); builder.beanDefinition.setBeanClass(beanClass); return builder; } @@ -76,8 +72,7 @@ public class BeanDefinitionBuilder { public static BeanDefinitionBuilder genericBeanDefinition( @Nullable Class beanClass, Supplier instanceSupplier) { - BeanDefinitionBuilder builder = new BeanDefinitionBuilder(); - builder.beanDefinition = new GenericBeanDefinition(); + BeanDefinitionBuilder builder = new BeanDefinitionBuilder(new GenericBeanDefinition()); builder.beanDefinition.setBeanClass(beanClass); builder.beanDefinition.setInstanceSupplier(instanceSupplier); return builder; @@ -97,8 +92,7 @@ public class BeanDefinitionBuilder { * @param factoryMethodName the name of the method to use to construct the bean instance */ public static BeanDefinitionBuilder rootBeanDefinition(String beanClassName, @Nullable String factoryMethodName) { - BeanDefinitionBuilder builder = new BeanDefinitionBuilder(); - builder.beanDefinition = new RootBeanDefinition(); + BeanDefinitionBuilder builder = new BeanDefinitionBuilder(new RootBeanDefinition()); builder.beanDefinition.setBeanClassName(beanClassName); builder.beanDefinition.setFactoryMethodName(factoryMethodName); return builder; @@ -118,8 +112,7 @@ public class BeanDefinitionBuilder { * @param factoryMethodName the name of the method to use to construct the bean instance */ public static BeanDefinitionBuilder rootBeanDefinition(Class beanClass, @Nullable String factoryMethodName) { - BeanDefinitionBuilder builder = new BeanDefinitionBuilder(); - builder.beanDefinition = new RootBeanDefinition(); + BeanDefinitionBuilder builder = new BeanDefinitionBuilder(new RootBeanDefinition()); builder.beanDefinition.setBeanClass(beanClass); builder.beanDefinition.setFactoryMethodName(factoryMethodName); return builder; @@ -130,16 +123,14 @@ public class BeanDefinitionBuilder { * @param parentName the name of the parent bean */ public static BeanDefinitionBuilder childBeanDefinition(String parentName) { - BeanDefinitionBuilder builder = new BeanDefinitionBuilder(); - builder.beanDefinition = new ChildBeanDefinition(parentName); - return builder; + return new BeanDefinitionBuilder(new ChildBeanDefinition(parentName)); } /** * The {@code BeanDefinition} instance we are creating. */ - private AbstractBeanDefinition beanDefinition; + private final AbstractBeanDefinition beanDefinition; /** * Our current position with respect to constructor args. @@ -150,7 +141,8 @@ public class BeanDefinitionBuilder { /** * Enforce the use of factory methods. */ - private BeanDefinitionBuilder() { + private BeanDefinitionBuilder(AbstractBeanDefinition beanDefinition) { + this.beanDefinition = beanDefinition; } /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultBeanDefinitionDocumentReader.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultBeanDefinitionDocumentReader.java index a7d900eb86d..436658546ec 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultBeanDefinitionDocumentReader.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultBeanDefinitionDocumentReader.java @@ -35,6 +35,7 @@ import org.springframework.beans.factory.support.BeanDefinitionReaderUtils; import org.springframework.core.io.Resource; import org.springframework.core.io.support.ResourcePatternUtils; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.ResourceUtils; import org.springframework.util.StringUtils; @@ -76,8 +77,10 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume protected final Log logger = LogFactory.getLog(getClass()); + @Nullable private XmlReaderContext readerContext; + @Nullable private BeanDefinitionParserDelegate delegate; @@ -99,6 +102,7 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume * Return the descriptor for the XML resource that this parser works on. */ protected final XmlReaderContext getReaderContext() { + Assert.state(this.readerContext != null, "No XmlReaderContext available"); return this.readerContext; } @@ -148,7 +152,7 @@ public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocume } protected BeanDefinitionParserDelegate createDelegate( - XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) { + XmlReaderContext readerContext, Element root, @Nullable BeanDefinitionParserDelegate parentDelegate) { BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext); delegate.initDefaults(root, parentDelegate); diff --git a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/ScheduledTimerListener.java b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/ScheduledTimerListener.java index c3e603882dc..b9fcfb09e0a 100644 --- a/spring-context-support/src/main/java/org/springframework/scheduling/commonj/ScheduledTimerListener.java +++ b/spring-context-support/src/main/java/org/springframework/scheduling/commonj/ScheduledTimerListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -18,6 +18,8 @@ package org.springframework.scheduling.commonj; import commonj.timers.TimerListener; +import org.springframework.lang.Nullable; + /** * JavaBean that describes a scheduled TimerListener, consisting of * the TimerListener itself (or a Runnable to create a TimerListener for) @@ -40,6 +42,7 @@ import commonj.timers.TimerListener; */ public class ScheduledTimerListener { + @Nullable private TimerListener timerListener; private long delay = 0; @@ -140,13 +143,14 @@ public class ScheduledTimerListener { /** * Set the TimerListener to schedule. */ - public void setTimerListener(TimerListener timerListener) { + public void setTimerListener(@Nullable TimerListener timerListener) { this.timerListener = timerListener; } /** * Return the TimerListener to schedule. */ + @Nullable public TimerListener getTimerListener() { return this.timerListener; } diff --git a/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java b/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java index 4e295bbb538..b9d90101bd6 100644 --- a/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java +++ b/spring-context-support/src/main/java/org/springframework/ui/freemarker/FreeMarkerConfigurationFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -24,6 +24,7 @@ import freemarker.template.TemplateException; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ResourceLoaderAware; +import org.springframework.lang.Nullable; /** * Factory bean that creates a FreeMarker Configuration and provides it as @@ -53,6 +54,7 @@ import org.springframework.context.ResourceLoaderAware; public class FreeMarkerConfigurationFactoryBean extends FreeMarkerConfigurationFactory implements FactoryBean, InitializingBean, ResourceLoaderAware { + @Nullable private Configuration configuration; diff --git a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java index 781448b7c90..7958bc8c24e 100644 --- a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java +++ b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -56,6 +56,7 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA private boolean storeByValue = false; + @Nullable private SerializationDelegate serialization; diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheInvoker.java b/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheInvoker.java index a1fc1fc6638..53fe359c04c 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheInvoker.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheInvoker.java @@ -38,7 +38,7 @@ public abstract class AbstractCacheInvoker { } protected AbstractCacheInvoker(CacheErrorHandler errorHandler) { - setErrorHandler(errorHandler); + this.errorHandler = errorHandler; } diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheResolver.java b/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheResolver.java index da8637cd0ac..815926be2d2 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheResolver.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractCacheResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -36,6 +36,7 @@ import org.springframework.util.Assert; */ public abstract class AbstractCacheResolver implements CacheResolver, InitializingBean { + @Nullable private CacheManager cacheManager; @@ -55,15 +56,16 @@ public abstract class AbstractCacheResolver implements CacheResolver, Initializi } /** - * Return the {@link CacheManager} that this instance use. + * Return the {@link CacheManager} that this instance uses. */ public CacheManager getCacheManager() { + Assert.state(this.cacheManager != null, "No CacheManager set"); return this.cacheManager; } @Override public void afterPropertiesSet() { - Assert.notNull(this.cacheManager, "CacheManager must not be null"); + Assert.notNull(this.cacheManager, "CacheManager is required"); } @@ -76,7 +78,7 @@ public abstract class AbstractCacheResolver implements CacheResolver, Initializi else { Collection result = new ArrayList<>(); for (String cacheName : cacheNames) { - Cache cache = this.cacheManager.getCache(cacheName); + Cache cache = getCacheManager().getCache(cacheName); if (cache == null) { throw new IllegalArgumentException("Cannot find cache named '" + cacheName + "' for " + context.getOperation()); diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java b/spring-context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java index 55a746f44fb..929bc667e2c 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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,6 +19,7 @@ package org.springframework.cache.interceptor; import org.springframework.aop.ClassFilter; import org.springframework.aop.Pointcut; import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor; +import org.springframework.lang.Nullable; /** * Advisor driven by a {@link CacheOperationSource}, used to include a @@ -30,6 +31,7 @@ import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor; @SuppressWarnings("serial") public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor { + @Nullable private CacheOperationSource cacheOperationSource; private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() { diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java index 01cf15f1096..8e08d27e1bc 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -16,6 +16,8 @@ package org.springframework.cache.interceptor; +import org.springframework.lang.Nullable; + /** * Class describing a cache 'put' operation. * @@ -26,6 +28,7 @@ package org.springframework.cache.interceptor; */ public class CachePutOperation extends CacheOperation { + @Nullable private final String unless; @@ -38,6 +41,7 @@ public class CachePutOperation extends CacheOperation { } + @Nullable public String getUnless() { return this.unless; } @@ -48,6 +52,7 @@ public class CachePutOperation extends CacheOperation { */ public static class Builder extends CacheOperation.Builder { + @Nullable private String unless; public void setUnless(String unless) { diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java index c3414e4da4b..30341f003b1 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -16,6 +16,8 @@ package org.springframework.cache.interceptor; +import org.springframework.lang.Nullable; + /** * Class describing a cache 'cacheable' operation. * @@ -26,6 +28,7 @@ package org.springframework.cache.interceptor; */ public class CacheableOperation extends CacheOperation { + @Nullable private final String unless; private final boolean sync; @@ -41,6 +44,7 @@ public class CacheableOperation extends CacheOperation { } + @Nullable public String getUnless() { return this.unless; } @@ -55,6 +59,7 @@ public class CacheableOperation extends CacheOperation { */ public static class Builder extends CacheOperation.Builder { + @Nullable private String unless; private boolean sync; diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/NamedCacheResolver.java b/spring-context/src/main/java/org/springframework/cache/interceptor/NamedCacheResolver.java index 543477410cf..9b128e739c5 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/NamedCacheResolver.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/NamedCacheResolver.java @@ -16,12 +16,12 @@ package org.springframework.cache.interceptor; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import org.springframework.cache.CacheManager; +import org.springframework.lang.Nullable; /** * A {@link CacheResolver} that forces the resolution to a configurable @@ -32,6 +32,7 @@ import org.springframework.cache.CacheManager; */ public class NamedCacheResolver extends AbstractCacheResolver { + @Nullable private Collection cacheNames; diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheErrorHandler.java b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheErrorHandler.java index fde1f536bd5..191873be64a 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheErrorHandler.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheErrorHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -17,6 +17,7 @@ package org.springframework.cache.interceptor; import org.springframework.cache.Cache; +import org.springframework.lang.Nullable; /** * A simple {@link CacheErrorHandler} that does not handle the @@ -33,7 +34,7 @@ public class SimpleCacheErrorHandler implements CacheErrorHandler { } @Override - public void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value) { + public void handleCachePutError(RuntimeException exception, Cache cache, Object key, @Nullable Object value) { throw exception; } diff --git a/spring-context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java b/spring-context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java index 5c373a2b70b..23dba09e038 100644 --- a/spring-context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java +++ b/spring-context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2017 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. @@ -17,6 +17,7 @@ package org.springframework.cache.support; import java.util.Collection; +import java.util.Collections; import org.springframework.cache.Cache; @@ -29,7 +30,7 @@ import org.springframework.cache.Cache; */ public class SimpleCacheManager extends AbstractCacheManager { - private Collection caches; + private Collection caches = Collections.emptySet(); /** diff --git a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java index 5cc0dccc259..557e8dbe110 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -53,6 +53,7 @@ final class ConfigurationClass { private final Resource resource; + @Nullable private String beanName; private final Set importedBy = new LinkedHashSet<>(1); @@ -75,7 +76,7 @@ final class ConfigurationClass { * @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass) */ public ConfigurationClass(MetadataReader metadataReader, String beanName) { - Assert.hasText(beanName, "Bean name must not be null"); + Assert.notNull(beanName, "Bean name must not be null"); this.metadata = metadataReader.getAnnotationMetadata(); this.resource = metadataReader.getResource(); this.beanName = beanName; @@ -102,7 +103,7 @@ final class ConfigurationClass { * @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass) */ public ConfigurationClass(Class clazz, String beanName) { - Assert.hasText(beanName, "Bean name must not be null"); + Assert.notNull(beanName, "Bean name must not be null"); this.metadata = new StandardAnnotationMetadata(clazz, true); this.resource = new DescriptiveResource(clazz.getName()); this.beanName = beanName; @@ -113,7 +114,7 @@ final class ConfigurationClass { * using the {@link Import} annotation or automatically processed as a nested * configuration class (if imported is {@code true}). * @param clazz the underlying {@link Class} to represent - * @param importedBy the configuration class importing this one or {@code null} + * @param importedBy the configuration class importing this one (or {@code null}) * @since 3.1.1 */ public ConfigurationClass(Class clazz, @Nullable ConfigurationClass importedBy) { @@ -129,7 +130,7 @@ final class ConfigurationClass { * @see ConfigurationClass#ConfigurationClass(Class, ConfigurationClass) */ public ConfigurationClass(AnnotationMetadata metadata, String beanName) { - Assert.hasText(beanName, "Bean name must not be null"); + Assert.notNull(beanName, "Bean name must not be null"); this.metadata = metadata; this.resource = new DescriptiveResource(metadata.getClassName()); this.beanName = beanName; @@ -152,6 +153,7 @@ final class ConfigurationClass { this.beanName = beanName; } + @Nullable public String getBeanName() { return this.beanName; } diff --git a/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java b/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java index 5640ebc4273..5b95f6100d3 100644 --- a/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/event/EventListenerMethodProcessor.java @@ -31,7 +31,6 @@ import org.springframework.aop.framework.autoproxy.AutoProxyUtils; import org.springframework.aop.scope.ScopedObject; import org.springframework.aop.scope.ScopedProxyUtils; import org.springframework.aop.support.AopUtils; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.context.ApplicationContext; @@ -41,6 +40,7 @@ import org.springframework.context.ConfigurableApplicationContext; import org.springframework.core.MethodIntrospector; import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotationAwareOrderComparator; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; @@ -56,6 +56,7 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton, protected final Log logger = LogFactory.getLog(getClass()); + @Nullable private ConfigurableApplicationContext applicationContext; private final EventExpressionEvaluator evaluator = new EventExpressionEvaluator(); @@ -64,21 +65,28 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton, @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + public void setApplicationContext(ApplicationContext applicationContext) { Assert.isTrue(applicationContext instanceof ConfigurableApplicationContext, "ApplicationContext does not implement ConfigurableApplicationContext"); this.applicationContext = (ConfigurableApplicationContext) applicationContext; } + private ConfigurableApplicationContext getApplicationContext() { + Assert.state(this.applicationContext != null, "No ApplicationContext set"); + return this.applicationContext; + } + + @Override public void afterSingletonsInstantiated() { List factories = getEventListenerFactories(); - String[] beanNames = this.applicationContext.getBeanNamesForType(Object.class); + ConfigurableApplicationContext context = getApplicationContext(); + String[] beanNames = context.getBeanNamesForType(Object.class); for (String beanName : beanNames) { if (!ScopedProxyUtils.isScopedTarget(beanName)) { Class type = null; try { - type = AutoProxyUtils.determineTargetClass(this.applicationContext.getBeanFactory(), beanName); + type = AutoProxyUtils.determineTargetClass(context.getBeanFactory(), beanName); } catch (Throwable ex) { // An unresolvable bean type, probably from a lazy bean - let's ignore it. @@ -90,8 +98,7 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton, if (ScopedObject.class.isAssignableFrom(type)) { try { Class targetClass = AutoProxyUtils.determineTargetClass( - this.applicationContext.getBeanFactory(), - ScopedProxyUtils.getTargetBeanName(beanName)); + context.getBeanFactory(), ScopedProxyUtils.getTargetBeanName(beanName)); if (targetClass != null) { type = targetClass; } @@ -121,7 +128,7 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton, * {@link EventListener} annotated methods. */ protected List getEventListenerFactories() { - Map beans = this.applicationContext.getBeansOfType(EventListenerFactory.class); + Map beans = getApplicationContext().getBeansOfType(EventListenerFactory.class); List allFactories = new ArrayList<>(beans.values()); AnnotationAwareOrderComparator.sort(allFactories); return allFactories; @@ -152,18 +159,17 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton, } else { // Non-empty set of methods + ConfigurableApplicationContext context = getApplicationContext(); for (Method method : annotatedMethods.keySet()) { for (EventListenerFactory factory : factories) { if (factory.supportsMethod(method)) { - Method methodToUse = AopUtils.selectInvocableMethod( - method, this.applicationContext.getType(beanName)); + Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName)); ApplicationListener applicationListener = factory.createApplicationListener(beanName, targetType, methodToUse); if (applicationListener instanceof ApplicationListenerMethodAdapter) { - ((ApplicationListenerMethodAdapter) applicationListener) - .init(this.applicationContext, this.evaluator); + ((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator); } - this.applicationContext.addApplicationListener(applicationListener); + context.addApplicationListener(applicationListener); break; } } diff --git a/spring-context/src/main/java/org/springframework/context/support/ApplicationListenerDetector.java b/spring-context/src/main/java/org/springframework/context/support/ApplicationListenerDetector.java index 66970bdaa8e..62b29b6aca6 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ApplicationListenerDetector.java +++ b/spring-context/src/main/java/org/springframework/context/support/ApplicationListenerDetector.java @@ -27,7 +27,6 @@ import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcess import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ApplicationEventMulticaster; -import org.springframework.lang.Nullable; import org.springframework.util.ObjectUtils; /** @@ -47,7 +46,6 @@ class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class); - @Nullable private transient final AbstractApplicationContext applicationContext; private transient final Map singletonNames = new ConcurrentHashMap<>(256); @@ -60,9 +58,7 @@ class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, @Override public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) { - if (this.applicationContext != null) { - this.singletonNames.put(beanName, beanDefinition.isSingleton()); - } + this.singletonNames.put(beanName, beanDefinition.isSingleton()); } @Override @@ -72,7 +68,7 @@ class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, @Override public Object postProcessAfterInitialization(Object bean, String beanName) { - if (this.applicationContext != null && bean instanceof ApplicationListener) { + if (bean instanceof ApplicationListener) { // potentially not detected as a listener by getBeanNamesForType retrieval Boolean flag = this.singletonNames.get(beanName); if (Boolean.TRUE.equals(flag)) { @@ -95,7 +91,7 @@ class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, @Override public void postProcessBeforeDestruction(Object bean, String beanName) { - if (this.applicationContext != null && bean instanceof ApplicationListener) { + if (bean instanceof ApplicationListener) { ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster(); multicaster.removeApplicationListener((ApplicationListener) bean); multicaster.removeApplicationListenerBean(beanName); diff --git a/spring-context/src/main/java/org/springframework/context/support/ClassPathXmlApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/ClassPathXmlApplicationContext.java index a85417caadd..5662a699e52 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ClassPathXmlApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/ClassPathXmlApplicationContext.java @@ -51,6 +51,7 @@ import org.springframework.util.Assert; */ public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext { + @Nullable private Resource[] configResources; @@ -203,6 +204,7 @@ public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContex @Override + @Nullable protected Resource[] getConfigResources() { return this.configResources; } diff --git a/spring-context/src/main/java/org/springframework/context/support/ConversionServiceFactoryBean.java b/spring-context/src/main/java/org/springframework/context/support/ConversionServiceFactoryBean.java index 2bba3f2c611..4991136b058 100644 --- a/spring-context/src/main/java/org/springframework/context/support/ConversionServiceFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/context/support/ConversionServiceFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -24,6 +24,7 @@ import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.support.ConversionServiceFactory; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.GenericConversionService; +import org.springframework.lang.Nullable; /** * A factory providing convenient access to a ConversionService configured with @@ -49,8 +50,10 @@ import org.springframework.core.convert.support.GenericConversionService; */ public class ConversionServiceFactoryBean implements FactoryBean, InitializingBean { + @Nullable private Set converters; + @Nullable private GenericConversionService conversionService; diff --git a/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java b/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java index d708b6ec8dd..88ff5e3cc44 100644 --- a/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/support/DefaultLifecycleProcessor.java @@ -39,6 +39,8 @@ import org.springframework.context.Lifecycle; import org.springframework.context.LifecycleProcessor; import org.springframework.context.Phased; import org.springframework.context.SmartLifecycle; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Default implementation of the {@link LifecycleProcessor} strategy. @@ -55,6 +57,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor private volatile boolean running; + @Nullable private volatile ConfigurableListableBeanFactory beanFactory; @@ -76,6 +79,12 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; } + private ConfigurableListableBeanFactory getBeanFactory() { + ConfigurableListableBeanFactory beanFactory = this.beanFactory; + Assert.state(beanFactory != null, "No BeanFactory available"); + return beanFactory; + } + // Lifecycle implementation @@ -161,7 +170,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor private void doStart(Map lifecycleBeans, String beanName, boolean autoStartupOnly) { Lifecycle bean = lifecycleBeans.remove(beanName); if (bean != null && !this.equals(bean)) { - String[] dependenciesForBean = this.beanFactory.getDependenciesForBean(beanName); + String[] dependenciesForBean = getBeanFactory().getDependenciesForBean(beanName); for (String dependency : dependenciesForBean) { doStart(lifecycleBeans, dependency, autoStartupOnly); } @@ -215,7 +224,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor Lifecycle bean = lifecycleBeans.remove(beanName); if (bean != null) { - String[] dependentBeans = this.beanFactory.getDependentBeans(beanName); + String[] dependentBeans = getBeanFactory().getDependentBeans(beanName); for (String dependentBean : dependentBeans) { doStop(lifecycleBeans, dependentBean, latch, countDownBeanNames); } @@ -266,16 +275,17 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor * @return the Map of applicable beans, with bean names as keys and bean instances as values */ protected Map getLifecycleBeans() { + ConfigurableListableBeanFactory beanFactory = getBeanFactory(); Map beans = new LinkedHashMap<>(); - String[] beanNames = this.beanFactory.getBeanNamesForType(Lifecycle.class, false, false); + String[] beanNames = getBeanFactory().getBeanNamesForType(Lifecycle.class, false, false); for (String beanName : beanNames) { String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName); - boolean isFactoryBean = this.beanFactory.isFactoryBean(beanNameToRegister); + boolean isFactoryBean = getBeanFactory().isFactoryBean(beanNameToRegister); String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName); - if ((this.beanFactory.containsSingleton(beanNameToRegister) && + if ((getBeanFactory().containsSingleton(beanNameToRegister) && (!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck))) || matchesBeanType(SmartLifecycle.class, beanNameToCheck)) { - Lifecycle bean = this.beanFactory.getBean(beanNameToCheck, Lifecycle.class); + Lifecycle bean = getBeanFactory().getBean(beanNameToCheck, Lifecycle.class); if (bean != this) { beans.put(beanNameToRegister, bean); } @@ -285,7 +295,7 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor } private boolean matchesBeanType(Class targetType, String beanName) { - Class beanType = this.beanFactory.getType(beanName); + Class beanType = getBeanFactory().getType(beanName); return (beanType != null && targetType.isAssignableFrom(beanType)); } diff --git a/spring-context/src/main/java/org/springframework/context/weaving/AspectJWeavingEnabler.java b/spring-context/src/main/java/org/springframework/context/weaving/AspectJWeavingEnabler.java index 5cb8a6194b2..98fead0a4d7 100644 --- a/spring-context/src/main/java/org/springframework/context/weaving/AspectJWeavingEnabler.java +++ b/spring-context/src/main/java/org/springframework/context/weaving/AspectJWeavingEnabler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -47,8 +47,10 @@ public class AspectJWeavingEnabler public static final String ASPECTJ_AOP_XML_RESOURCE = "META-INF/aop.xml"; + @Nullable private ClassLoader beanClassLoader; + @Nullable private LoadTimeWeaver loadTimeWeaver; diff --git a/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBean.java b/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBean.java index b6aa7ef63ad..08b43009034 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/joda/DateTimeFormatterFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 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 org.joda.time.format.DateTimeFormatter; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.lang.Nullable; /** * {@link FactoryBean} that creates a Joda-Time {@link DateTimeFormatter}. @@ -36,6 +37,7 @@ import org.springframework.beans.factory.InitializingBean; public class DateTimeFormatterFactoryBean extends DateTimeFormatterFactory implements FactoryBean, InitializingBean { + @Nullable private DateTimeFormatter dateTimeFormatter; diff --git a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterFactoryBean.java b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterFactoryBean.java index f2d98d750f9..4c805ab1dc1 100644 --- a/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/format/datetime/standard/DateTimeFormatterFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 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.time.format.DateTimeFormatter; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.lang.Nullable; /** * {@link FactoryBean} that creates a JSR-310 {@link java.time.format.DateTimeFormatter}. @@ -36,6 +37,7 @@ import org.springframework.beans.factory.InitializingBean; public class DateTimeFormatterFactoryBean extends DateTimeFormatterFactory implements FactoryBean, InitializingBean { + @Nullable private DateTimeFormatter dateTimeFormatter; diff --git a/spring-context/src/main/java/org/springframework/jmx/export/assembler/MetadataMBeanInfoAssembler.java b/spring-context/src/main/java/org/springframework/jmx/export/assembler/MetadataMBeanInfoAssembler.java index 1fa216ee622..620843f3fda 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/assembler/MetadataMBeanInfoAssembler.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/assembler/MetadataMBeanInfoAssembler.java @@ -432,7 +432,8 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem * @param setter the Object value associated with the set method * @return the appropriate Object to use as the value for the descriptor */ - private Object resolveObjectDescriptor(@Nullable Object getter, Object setter) { + @Nullable + private Object resolveObjectDescriptor(@Nullable Object getter, @Nullable Object setter) { return (getter != null ? getter : setter); } @@ -446,7 +447,8 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem * @param setter the String value associated with the set method * @return the appropriate String to use as the value for the descriptor */ - private String resolveStringDescriptor(String getter, String setter) { + @Nullable + private String resolveStringDescriptor(@Nullable String getter, @Nullable String setter) { return (StringUtils.hasLength(getter) ? getter : setter); } diff --git a/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedAttribute.java b/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedAttribute.java index 2831ac92c30..df7d7dc4455 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedAttribute.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 the original author or authors. + * Copyright 2002-2017 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. @@ -16,6 +16,8 @@ package org.springframework.jmx.export.metadata; +import org.springframework.lang.Nullable; + /** * Metadata that indicates to expose a given bean property as JMX attribute. * Only valid when used on a JavaBean getter or setter. @@ -30,8 +32,10 @@ public class ManagedAttribute extends AbstractJmxAttribute { public static final ManagedAttribute EMPTY = new ManagedAttribute(); + @Nullable private Object defaultValue; + @Nullable private String persistPolicy; private int persistPeriod = -1; @@ -40,21 +44,23 @@ public class ManagedAttribute extends AbstractJmxAttribute { /** * Set the default value of this attribute. */ - public void setDefaultValue(Object defaultValue) { + public void setDefaultValue(@Nullable Object defaultValue) { this.defaultValue = defaultValue; } /** * Return the default value of this attribute. */ + @Nullable public Object getDefaultValue() { return this.defaultValue; } - public void setPersistPolicy(String persistPolicy) { + public void setPersistPolicy(@Nullable String persistPolicy) { this.persistPolicy = persistPolicy; } + @Nullable public String getPersistPolicy() { return this.persistPolicy; } diff --git a/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedMetric.java b/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedMetric.java index 22103b6667d..a116cafaecf 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedMetric.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedMetric.java @@ -17,6 +17,7 @@ package org.springframework.jmx.export.metadata; import org.springframework.jmx.support.MetricType; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -30,29 +31,34 @@ import org.springframework.util.Assert; */ public class ManagedMetric extends AbstractJmxAttribute { + @Nullable private String category; + @Nullable private String displayName; private MetricType metricType = MetricType.GAUGE; private int persistPeriod = -1; + @Nullable private String persistPolicy; + @Nullable private String unit; /** * The category of this metric (ex. throughput, performance, utilization). */ - public void setCategory(String category) { + public void setCategory(@Nullable String category) { this.category = category; } /** * The category of this metric (ex. throughput, performance, utilization). */ + @Nullable public String getCategory() { return this.category; } @@ -60,13 +66,14 @@ public class ManagedMetric extends AbstractJmxAttribute { /** * A display name for this metric. */ - public void setDisplayName(String displayName) { + public void setDisplayName(@Nullable String displayName) { this.displayName = displayName; } /** * A display name for this metric. */ + @Nullable public String getDisplayName() { return this.displayName; } @@ -103,13 +110,14 @@ public class ManagedMetric extends AbstractJmxAttribute { /** * The persist policy for this metric. */ - public void setPersistPolicy(String persistPolicy) { + public void setPersistPolicy(@Nullable String persistPolicy) { this.persistPolicy = persistPolicy; } /** * The persist policy for this metric. */ + @Nullable public String getPersistPolicy() { return this.persistPolicy; } @@ -117,13 +125,14 @@ public class ManagedMetric extends AbstractJmxAttribute { /** * The expected unit of measurement values. */ - public void setUnit(String unit) { + public void setUnit(@Nullable String unit) { this.unit = unit; } /** * The expected unit of measurement values. */ + @Nullable public String getUnit() { return this.unit; } diff --git a/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedResource.java b/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedResource.java index 9fd41123c2d..3ef31d9fd17 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedResource.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/metadata/ManagedResource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -16,6 +16,8 @@ package org.springframework.jmx.export.metadata; +import org.springframework.lang.Nullable; + /** * Metadata indicating that instances of an annotated class * are to be registered with a JMX server. @@ -29,31 +31,37 @@ package org.springframework.jmx.export.metadata; */ public class ManagedResource extends AbstractJmxAttribute { + @Nullable private String objectName; private boolean log = false; + @Nullable private String logFile; + @Nullable private String persistPolicy; private int persistPeriod = -1; + @Nullable private String persistName; + @Nullable private String persistLocation; /** * Set the JMX ObjectName of this managed resource. */ - public void setObjectName(String objectName) { + public void setObjectName(@Nullable String objectName) { this.objectName = objectName; } /** * Return the JMX ObjectName of this managed resource. */ + @Nullable public String getObjectName() { return this.objectName; } @@ -66,18 +74,20 @@ public class ManagedResource extends AbstractJmxAttribute { return this.log; } - public void setLogFile(String logFile) { + public void setLogFile(@Nullable String logFile) { this.logFile = logFile; } + @Nullable public String getLogFile() { return this.logFile; } - public void setPersistPolicy(String persistPolicy) { + public void setPersistPolicy(@Nullable String persistPolicy) { this.persistPolicy = persistPolicy; } + @Nullable public String getPersistPolicy() { return this.persistPolicy; } @@ -90,18 +100,20 @@ public class ManagedResource extends AbstractJmxAttribute { return this.persistPeriod; } - public void setPersistName(String persistName) { + public void setPersistName(@Nullable String persistName) { this.persistName = persistName; } + @Nullable public String getPersistName() { return this.persistName; } - public void setPersistLocation(String persistLocation) { + public void setPersistLocation(@Nullable String persistLocation) { this.persistLocation = persistLocation; } + @Nullable public String getPersistLocation() { return this.persistLocation; } diff --git a/spring-context/src/main/java/org/springframework/jndi/TypeMismatchNamingException.java b/spring-context/src/main/java/org/springframework/jndi/TypeMismatchNamingException.java index c82108a9124..3d2513ff74b 100644 --- a/spring-context/src/main/java/org/springframework/jndi/TypeMismatchNamingException.java +++ b/spring-context/src/main/java/org/springframework/jndi/TypeMismatchNamingException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -29,9 +29,9 @@ import javax.naming.NamingException; @SuppressWarnings("serial") public class TypeMismatchNamingException extends NamingException { - private Class requiredType; + private final Class requiredType; - private Class actualType; + private final Class actualType; /** @@ -48,14 +48,6 @@ public class TypeMismatchNamingException extends NamingException { this.actualType = actualType; } - /** - * Construct a new TypeMismatchNamingException. - * @param explanation the explanation text - */ - public TypeMismatchNamingException(String explanation) { - super(explanation); - } - /** * Return the required type for the lookup, if available. diff --git a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java index b5e4afed744..c5bacdf28dc 100644 --- a/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java +++ b/spring-context/src/main/java/org/springframework/remoting/support/RemoteInvocationResult.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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.io.Serializable; import java.lang.reflect.InvocationTargetException; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Encapsulates a remote invocation result, holding a result value or an exception. @@ -53,7 +54,7 @@ public class RemoteInvocationResult implements Serializable { * @param value the result value returned by a successful invocation * of the target method */ - public RemoteInvocationResult(Object value) { + public RemoteInvocationResult(@Nullable Object value) { this.value = value; } @@ -62,7 +63,7 @@ public class RemoteInvocationResult implements Serializable { * @param exception the exception thrown by an unsuccessful invocation * of the target method */ - public RemoteInvocationResult(Throwable exception) { + public RemoteInvocationResult(@Nullable Throwable exception) { this.exception = exception; } diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java index a662e018142..d10f162cd31 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskExecutor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -88,17 +88,19 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche * @see java.util.concurrent.Executors#newSingleThreadExecutor() */ public ConcurrentTaskExecutor() { - setConcurrentExecutor(null); + this.concurrentExecutor = Executors.newSingleThreadExecutor(); + this.adaptedExecutor = new TaskExecutorAdapter(this.concurrentExecutor); } /** * Create a new ConcurrentTaskExecutor, using the given {@link java.util.concurrent.Executor}. *

Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedExecutorService} * in order to expose {@link javax.enterprise.concurrent.ManagedTask} adapters for it. - * @param concurrentExecutor the {@link java.util.concurrent.Executor} to delegate to + * @param executor the {@link java.util.concurrent.Executor} to delegate to */ - public ConcurrentTaskExecutor(Executor concurrentExecutor) { - setConcurrentExecutor(concurrentExecutor); + public ConcurrentTaskExecutor(@Nullable Executor executor) { + this.concurrentExecutor = (executor != null ? executor : Executors.newSingleThreadExecutor()); + this.adaptedExecutor = getAdaptedExecutor(this.concurrentExecutor); } @@ -107,20 +109,9 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche *

Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedExecutorService} * in order to expose {@link javax.enterprise.concurrent.ManagedTask} adapters for it. */ - public final void setConcurrentExecutor(@Nullable Executor concurrentExecutor) { - if (concurrentExecutor != null) { - this.concurrentExecutor = concurrentExecutor; - if (managedExecutorServiceClass != null && managedExecutorServiceClass.isInstance(concurrentExecutor)) { - this.adaptedExecutor = new ManagedTaskExecutorAdapter(concurrentExecutor); - } - else { - this.adaptedExecutor = new TaskExecutorAdapter(concurrentExecutor); - } - } - else { - this.concurrentExecutor = Executors.newSingleThreadExecutor(); - this.adaptedExecutor = new TaskExecutorAdapter(this.concurrentExecutor); - } + public final void setConcurrentExecutor(@Nullable Executor executor) { + this.concurrentExecutor = (executor != null ? executor : Executors.newSingleThreadExecutor()); + this.adaptedExecutor = getAdaptedExecutor(this.concurrentExecutor); } /** @@ -184,6 +175,14 @@ public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, Sche } + private static TaskExecutorAdapter getAdaptedExecutor(Executor concurrentExecutor) { + if (managedExecutorServiceClass != null && managedExecutorServiceClass.isInstance(concurrentExecutor)) { + return new ManagedTaskExecutorAdapter(concurrentExecutor); + } + return new TaskExecutorAdapter(concurrentExecutor); + } + + /** * TaskExecutorAdapter subclass that wraps all provided Runnables and Callables * with a JSR-236 ManagedTask, exposing a long-running hint based on diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ForkJoinPoolFactoryBean.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ForkJoinPoolFactoryBean.java index bad0fdd27b0..4801edbbea1 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ForkJoinPoolFactoryBean.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ForkJoinPoolFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -22,6 +22,7 @@ import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.lang.Nullable; /** * A Spring {@link FactoryBean} that builds and exposes a preconfigured {@link ForkJoinPool}. @@ -43,12 +44,14 @@ public class ForkJoinPoolFactoryBean implements FactoryBean, Initi private ForkJoinPool.ForkJoinWorkerThreadFactory threadFactory = ForkJoinPool.defaultForkJoinWorkerThreadFactory; + @Nullable private Thread.UncaughtExceptionHandler uncaughtExceptionHandler; private boolean asyncMode = false; private int awaitTerminationSeconds = 0; + @Nullable private ForkJoinPool forkJoinPool; @@ -148,16 +151,18 @@ public class ForkJoinPoolFactoryBean implements FactoryBean, Initi @Override public void destroy() { - // Ignored for the common pool. - this.forkJoinPool.shutdown(); + if (this.forkJoinPool != null) { + // Ignored for the common pool. + this.forkJoinPool.shutdown(); - // Wait for all tasks to terminate - works for the common pool as well. - if (this.awaitTerminationSeconds > 0) { - try { - this.forkJoinPool.awaitTermination(this.awaitTerminationSeconds, TimeUnit.SECONDS); - } - catch (InterruptedException ex) { - Thread.currentThread().interrupt(); + // Wait for all tasks to terminate - works for the common pool as well. + if (this.awaitTerminationSeconds > 0) { + try { + this.forkJoinPool.awaitTermination(this.awaitTerminationSeconds, TimeUnit.SECONDS); + } + catch (InterruptedException ex) { + Thread.currentThread().interrupt(); + } } } } diff --git a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ScheduledExecutorTask.java b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ScheduledExecutorTask.java index 9326ba0ca28..14222b882a0 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/concurrent/ScheduledExecutorTask.java +++ b/spring-context/src/main/java/org/springframework/scheduling/concurrent/ScheduledExecutorTask.java @@ -19,6 +19,7 @@ package org.springframework.scheduling.concurrent; import java.util.concurrent.TimeUnit; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * JavaBean that describes a scheduled executor task, consisting of the @@ -40,6 +41,7 @@ import org.springframework.lang.Nullable; */ public class ScheduledExecutorTask { + @Nullable private Runnable runnable; private long delay = 0; @@ -107,6 +109,7 @@ public class ScheduledExecutorTask { * Return the Runnable to schedule as executor task. */ public Runnable getRunnable() { + Assert.state(this.runnable != null, "No Runnable set"); return this.runnable; } diff --git a/spring-context/src/main/java/org/springframework/scheduling/support/SimpleTriggerContext.java b/spring-context/src/main/java/org/springframework/scheduling/support/SimpleTriggerContext.java index 289388cee09..afad1f594f9 100644 --- a/spring-context/src/main/java/org/springframework/scheduling/support/SimpleTriggerContext.java +++ b/spring-context/src/main/java/org/springframework/scheduling/support/SimpleTriggerContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 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. @@ -18,6 +18,7 @@ package org.springframework.scheduling.support; import java.util.Date; +import org.springframework.lang.Nullable; import org.springframework.scheduling.TriggerContext; /** @@ -28,10 +29,13 @@ import org.springframework.scheduling.TriggerContext; */ public class SimpleTriggerContext implements TriggerContext { + @Nullable private volatile Date lastScheduledExecutionTime; + @Nullable private volatile Date lastActualExecutionTime; + @Nullable private volatile Date lastCompletionTime; diff --git a/spring-context/src/main/java/org/springframework/scripting/ScriptCompilationException.java b/spring-context/src/main/java/org/springframework/scripting/ScriptCompilationException.java index ec0660be0b3..0333c6d2633 100644 --- a/spring-context/src/main/java/org/springframework/scripting/ScriptCompilationException.java +++ b/spring-context/src/main/java/org/springframework/scripting/ScriptCompilationException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -28,6 +28,7 @@ import org.springframework.lang.Nullable; @SuppressWarnings("serial") public class ScriptCompilationException extends NestedRuntimeException { + @Nullable private ScriptSource scriptSource; diff --git a/spring-context/src/main/java/org/springframework/scripting/bsh/BshScriptEvaluator.java b/spring-context/src/main/java/org/springframework/scripting/bsh/BshScriptEvaluator.java index 923282c550c..0e2f8315fb8 100644 --- a/spring-context/src/main/java/org/springframework/scripting/bsh/BshScriptEvaluator.java +++ b/spring-context/src/main/java/org/springframework/scripting/bsh/BshScriptEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -38,6 +38,7 @@ import org.springframework.scripting.ScriptSource; */ public class BshScriptEvaluator implements ScriptEvaluator, BeanClassLoaderAware { + @Nullable private ClassLoader classLoader; diff --git a/spring-context/src/main/java/org/springframework/ui/ExtendedModelMap.java b/spring-context/src/main/java/org/springframework/ui/ExtendedModelMap.java index 6ec5b005a9f..94eede9d8d0 100644 --- a/spring-context/src/main/java/org/springframework/ui/ExtendedModelMap.java +++ b/spring-context/src/main/java/org/springframework/ui/ExtendedModelMap.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -49,19 +49,19 @@ public class ExtendedModelMap extends ModelMap implements Model { } @Override - public ExtendedModelMap addAllAttributes(Collection attributeValues) { + public ExtendedModelMap addAllAttributes(@Nullable Collection attributeValues) { super.addAllAttributes(attributeValues); return this; } @Override - public ExtendedModelMap addAllAttributes(Map attributes) { + public ExtendedModelMap addAllAttributes(@Nullable Map attributes) { super.addAllAttributes(attributes); return this; } @Override - public ExtendedModelMap mergeAttributes(Map attributes) { + public ExtendedModelMap mergeAttributes(@Nullable Map attributes) { super.mergeAttributes(attributes); return this; } diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java index fb9ad0cb6b9..f1e1f296f61 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationPostProcessor.java @@ -62,6 +62,7 @@ public class MethodValidationPostProcessor extends AbstractBeanFactoryAwareAdvis private Class validatedAnnotationType = Validated.class; + @Nullable private Validator validator; diff --git a/spring-context/src/test/java/org/springframework/aop/config/AopNamespaceHandlerTests.java b/spring-context/src/test/java/org/springframework/aop/config/AopNamespaceHandlerTests.java index ef635d71920..ac89a979e9c 100644 --- a/spring-context/src/test/java/org/springframework/aop/config/AopNamespaceHandlerTests.java +++ b/spring-context/src/test/java/org/springframework/aop/config/AopNamespaceHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 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. @@ -43,9 +43,8 @@ public class AopNamespaceHandlerTests { @Before - public void setUp() { - this.context = - new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass()); + public void setup() { + this.context = new ClassPathXmlApplicationContext(getClass().getSimpleName() + "-context.xml", getClass()); } protected ITestBean getTestBean() { @@ -108,7 +107,27 @@ public class AopNamespaceHandlerTests { } @Test - public void testAspectAppliedForInitializeBean() { + public void testAspectAppliedForInitializeBeanWithEmptyName() { + ITestBean bean = (ITestBean) this.context.getAutowireCapableBeanFactory().initializeBean(new TestBean(), ""); + + CountingAspectJAdvice advice = (CountingAspectJAdvice) this.context.getBean("countingAdvice"); + + assertEquals("Incorrect before count", 0, advice.getBeforeCount()); + assertEquals("Incorrect after count", 0, advice.getAfterCount()); + + bean.setName("Sally"); + + assertEquals("Incorrect before count", 1, advice.getBeforeCount()); + assertEquals("Incorrect after count", 1, advice.getAfterCount()); + + bean.getName(); + + assertEquals("Incorrect before count", 1, advice.getBeforeCount()); + assertEquals("Incorrect after count", 1, advice.getAfterCount()); + } + + @Test + public void testAspectAppliedForInitializeBeanWithNullName() { ITestBean bean = (ITestBean) this.context.getAutowireCapableBeanFactory().initializeBean(new TestBean(), null); CountingAspectJAdvice advice = (CountingAspectJAdvice) this.context.getBean("countingAdvice"); @@ -126,6 +145,7 @@ public class AopNamespaceHandlerTests { assertEquals("Incorrect before count", 1, advice.getBeforeCount()); assertEquals("Incorrect after count", 1, advice.getAfterCount()); } + } diff --git a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java index 7fe2fd2aa11..ee0c58ef854 100644 --- a/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/ReactiveAdapterRegistry.java @@ -30,10 +30,7 @@ import rx.RxReactiveStreams; import org.springframework.lang.Nullable; -import static org.springframework.core.ReactiveTypeDescriptor.multiValue; -import static org.springframework.core.ReactiveTypeDescriptor.noValue; -import static org.springframework.core.ReactiveTypeDescriptor.singleOptionalValue; -import static org.springframework.core.ReactiveTypeDescriptor.singleRequiredValue; +import static org.springframework.core.ReactiveTypeDescriptor.*; /** * A registry of adapters to adapt a Reactive Streams {@link Publisher} to/from @@ -250,7 +247,7 @@ public class ReactiveAdapterRegistry { } @Override - public Publisher toPublisher(Object source) { + public Publisher toPublisher(@Nullable Object source) { Publisher publisher = super.toPublisher(source); return (isMultiValue() ? Flux.from(publisher) : Mono.from(publisher)); } diff --git a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java index 7c85aba97db..e79d19145d5 100644 --- a/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java +++ b/spring-core/src/main/java/org/springframework/core/type/classreading/AnnotationAttributesReadingVisitor.java @@ -47,7 +47,6 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib private final MultiValueMap attributesMap; - @Nullable private final Map> metaAnnotationMap; @@ -83,13 +82,11 @@ final class AnnotationAttributesReadingVisitor extends RecursiveAnnotationAttrib } } } - if (this.metaAnnotationMap != null) { - Set metaAnnotationTypeNames = new LinkedHashSet<>(visited.size()); - for (Annotation ann : visited) { - metaAnnotationTypeNames.add(ann.annotationType().getName()); - } - this.metaAnnotationMap.put(annotationClass.getName(), metaAnnotationTypeNames); + Set metaAnnotationTypeNames = new LinkedHashSet<>(visited.size()); + for (Annotation ann : visited) { + metaAnnotationTypeNames.add(ann.annotationType().getName()); } + this.metaAnnotationMap.put(annotationClass.getName(), metaAnnotationTypeNames); } } diff --git a/spring-core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java b/spring-core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java index be517a17016..9cb84fcec62 100644 --- a/spring-core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java +++ b/spring-core/src/main/java/org/springframework/util/xml/StaxEventXMLReader.java @@ -66,6 +66,7 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { private String xmlVersion = DEFAULT_XML_VERSION; + @Nullable private String encoding; @@ -77,7 +78,7 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { * @throws IllegalStateException if the reader is not at the start of a document or element */ StaxEventXMLReader(XMLEventReader reader) { - Assert.notNull(reader, "'reader' must not be null"); + Assert.notNull(reader, "XMLEventReader must not be null"); try { XMLEvent event = reader.peek(); if (event != null && !(event.isStartDocument() || event.isStartElement())) { @@ -189,6 +190,7 @@ class StaxEventXMLReader extends AbstractStaxXMLReader { return xmlVersion; } @Override + @Nullable public String getEncoding() { return encoding; } diff --git a/spring-core/src/main/java/org/springframework/util/xml/StaxResult.java b/spring-core/src/main/java/org/springframework/util/xml/StaxResult.java index cc78ddbee65..4e5bdd51dbe 100644 --- a/spring-core/src/main/java/org/springframework/util/xml/StaxResult.java +++ b/spring-core/src/main/java/org/springframework/util/xml/StaxResult.java @@ -48,22 +48,13 @@ import org.springframework.lang.Nullable; */ class StaxResult extends SAXResult { + @Nullable private XMLEventWriter eventWriter; + @Nullable private XMLStreamWriter streamWriter; - /** - * Construct a new instance of the {@code StaxResult} with the specified {@code XMLStreamWriter}. - * @param streamWriter the {@code XMLStreamWriter} to write to - */ - public StaxResult(XMLStreamWriter streamWriter) { - StaxStreamHandler handler = new StaxStreamHandler(streamWriter); - super.setHandler(handler); - super.setLexicalHandler(handler); - this.streamWriter = streamWriter; - } - /** * Construct a new instance of the {@code StaxResult} with the specified {@code XMLEventWriter}. * @param eventWriter the {@code XMLEventWriter} to write to @@ -75,6 +66,17 @@ class StaxResult extends SAXResult { this.eventWriter = eventWriter; } + /** + * Construct a new instance of the {@code StaxResult} with the specified {@code XMLStreamWriter}. + * @param streamWriter the {@code XMLStreamWriter} to write to + */ + public StaxResult(XMLStreamWriter streamWriter) { + StaxStreamHandler handler = new StaxStreamHandler(streamWriter); + super.setHandler(handler); + super.setLexicalHandler(handler); + this.streamWriter = streamWriter; + } + /** * Return the {@code XMLEventWriter} used by this {@code StaxResult}. diff --git a/spring-core/src/main/java/org/springframework/util/xml/StaxSource.java b/spring-core/src/main/java/org/springframework/util/xml/StaxSource.java index d56e96a6644..83828376d94 100644 --- a/spring-core/src/main/java/org/springframework/util/xml/StaxSource.java +++ b/spring-core/src/main/java/org/springframework/util/xml/StaxSource.java @@ -47,23 +47,13 @@ import org.springframework.lang.Nullable; */ class StaxSource extends SAXSource { + @Nullable private XMLEventReader eventReader; + @Nullable private XMLStreamReader streamReader; - /** - * Construct a new instance of the {@code StaxSource} with the specified {@code XMLStreamReader}. - * The supplied stream reader must be in {@code XMLStreamConstants.START_DOCUMENT} or - * {@code XMLStreamConstants.START_ELEMENT} state. - * @param streamReader the {@code XMLStreamReader} to read from - * @throws IllegalStateException if the reader is not at the start of a document or element - */ - StaxSource(XMLStreamReader streamReader) { - super(new StaxStreamXMLReader(streamReader), new InputSource()); - this.streamReader = streamReader; - } - /** * Construct a new instance of the {@code StaxSource} with the specified {@code XMLEventReader}. * The supplied event reader must be in {@code XMLStreamConstants.START_DOCUMENT} or @@ -76,6 +66,18 @@ class StaxSource extends SAXSource { this.eventReader = eventReader; } + /** + * Construct a new instance of the {@code StaxSource} with the specified {@code XMLStreamReader}. + * The supplied stream reader must be in {@code XMLStreamConstants.START_DOCUMENT} or + * {@code XMLStreamConstants.START_ELEMENT} state. + * @param streamReader the {@code XMLStreamReader} to read from + * @throws IllegalStateException if the reader is not at the start of a document or element + */ + StaxSource(XMLStreamReader streamReader) { + super(new StaxStreamXMLReader(streamReader), new InputSource()); + this.streamReader = streamReader; + } + /** * Return the {@code XMLEventReader} used by this {@code StaxSource}. diff --git a/spring-core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java b/spring-core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java index e69ad51660b..06c9a7069d1 100644 --- a/spring-core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java +++ b/spring-core/src/main/java/org/springframework/util/xml/StaxStreamXMLReader.java @@ -51,6 +51,7 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { private String xmlVersion = DEFAULT_XML_VERSION; + @Nullable private String encoding; @@ -62,7 +63,7 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { * @throws IllegalStateException if the reader is not at the start of a document or element */ StaxStreamXMLReader(XMLStreamReader reader) { - Assert.notNull(reader, "'reader' must not be null"); + Assert.notNull(reader, "XMLStreamReader must not be null"); int event = reader.getEventType(); if (!(event == XMLStreamConstants.START_DOCUMENT || event == XMLStreamConstants.START_ELEMENT)) { throw new IllegalStateException("XMLEventReader not at start of document or element"); @@ -166,6 +167,7 @@ class StaxStreamXMLReader extends AbstractStaxXMLReader { return xmlVersion; } @Override + @Nullable public String getEncoding() { return encoding; } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java index 6d739ed30c8..a664e3ab723 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -22,6 +22,7 @@ import org.springframework.expression.TypedValue; import org.springframework.expression.spel.CodeFlow; import org.springframework.expression.spel.ExpressionState; import org.springframework.expression.spel.SpelEvaluationException; +import org.springframework.lang.Nullable; /** * Represents a DOT separated expression sequence, such as 'property1.property2.methodOne()' @@ -91,7 +92,7 @@ public class CompoundExpression extends SpelNodeImpl { } @Override - public void setValue(ExpressionState state, Object value) throws EvaluationException { + public void setValue(ExpressionState state, @Nullable Object value) throws EvaluationException { getValueRef(state).setValue(value); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorInstanceof.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorInstanceof.java index e5559167838..57513f6768c 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorInstanceof.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorInstanceof.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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,7 +25,8 @@ import org.springframework.expression.spel.ExpressionState; import org.springframework.expression.spel.SpelEvaluationException; import org.springframework.expression.spel.SpelMessage; import org.springframework.expression.spel.support.BooleanTypedValue; - +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * The operator 'instanceof' checks if an object is of the class specified in the right @@ -36,8 +37,10 @@ import org.springframework.expression.spel.support.BooleanTypedValue; */ public class OperatorInstanceof extends Operator { + @Nullable private Class type; + public OperatorInstanceof(int pos, SpelNodeImpl... operands) { super("instanceof", pos, operands); } @@ -47,8 +50,8 @@ public class OperatorInstanceof extends Operator { * Compare the left operand to see it is an instance of the type specified as the * right operand. The right operand must be a class. * @param state the expression state - * @return true if the left operand is an instanceof of the right operand, otherwise - * false + * @return {@code true} if the left operand is an instanceof of the right operand, + * otherwise {@code false} * @throws EvaluationException if there is a problem evaluating the expression */ @Override @@ -58,7 +61,7 @@ public class OperatorInstanceof extends Operator { TypedValue right = rightOperand.getValueInternal(state); Object leftValue = left.getValue(); Object rightValue = right.getValue(); - BooleanTypedValue result = null; + BooleanTypedValue result; if (rightValue == null || !(rightValue instanceof Class)) { throw new SpelEvaluationException(getRightOperand().getStartPosition(), SpelMessage.INSTANCEOF_OPERATOR_NEEDS_CLASS_OPERAND, @@ -89,6 +92,7 @@ public class OperatorInstanceof extends Operator { public void generateCode(MethodVisitor mv, CodeFlow cf) { getLeftOperand().generateCode(mv, cf); CodeFlow.insertBoxIfNecessary(mv, cf.lastDescriptor()); + Assert.state(this.type != null, "No type available"); if (this.type.isPrimitive()) { // always false - but left operand code always driven // in case it had side effects @@ -96,7 +100,7 @@ public class OperatorInstanceof extends Operator { mv.visitInsn(ICONST_0); // value of false } else { - mv.visitTypeInsn(INSTANCEOF,Type.getInternalName(this.type)); + mv.visitTypeInsn(INSTANCEOF, Type.getInternalName(this.type)); } cf.pushDescriptor(this.exitTypeDescriptor); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java index a2889681899..8f96013cf07 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/TypeReference.java @@ -24,6 +24,7 @@ import org.springframework.expression.EvaluationException; import org.springframework.expression.TypedValue; import org.springframework.expression.spel.CodeFlow; import org.springframework.expression.spel.ExpressionState; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -35,15 +36,16 @@ public class TypeReference extends SpelNodeImpl { private final int dimensions; + @Nullable private transient Class type; public TypeReference(int pos, SpelNodeImpl qualifiedId) { - this(pos,qualifiedId,0); + this(pos, qualifiedId, 0); } public TypeReference(int pos, SpelNodeImpl qualifiedId, int dims) { - super(pos,qualifiedId); + super(pos, qualifiedId); this.dimensions = dims; } @@ -99,6 +101,7 @@ public class TypeReference extends SpelNodeImpl { @Override public void generateCode(MethodVisitor mv, CodeFlow cf) { // TODO Future optimization - if followed by a static method call, skip generating code here + Assert.state(this.type != null, "No type available"); if (this.type.isPrimitive()) { if (this.type == Integer.TYPE) { mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java index 9fba93a4f5e..85f47c4dfb5 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/ValueRef.java @@ -68,7 +68,7 @@ public interface ValueRef { } @Override - public void setValue(Object newValue) { + public void setValue(@Nullable Object newValue) { // The exception position '0' isn't right but the overhead of creating // instances of this per node (where the node is solely for error reporting) // would be unfortunate. @@ -102,7 +102,7 @@ public interface ValueRef { } @Override - public void setValue(Object newValue) { + public void setValue(@Nullable Object newValue) { throw new SpelEvaluationException(this.node.pos, SpelMessage.NOT_ASSIGNABLE, this.node.toStringAST()); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java index d3f3917e754..9786eac55b2 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java @@ -157,6 +157,7 @@ public class StandardEvaluationContext implements EvaluationContext { } @Override + @Nullable public BeanResolver getBeanResolver() { return this.beanResolver; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/InvalidResultSetAccessException.java b/spring-jdbc/src/main/java/org/springframework/jdbc/InvalidResultSetAccessException.java index 64b402d2c7e..0089a1aecb4 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/InvalidResultSetAccessException.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/InvalidResultSetAccessException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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,6 +19,7 @@ package org.springframework.jdbc; import java.sql.SQLException; import org.springframework.dao.InvalidDataAccessResourceUsageException; +import org.springframework.lang.Nullable; /** * Exception thrown when a ResultSet has been accessed in an invalid fashion. @@ -35,6 +36,7 @@ import org.springframework.dao.InvalidDataAccessResourceUsageException; @SuppressWarnings("serial") public class InvalidResultSetAccessException extends InvalidDataAccessResourceUsageException { + @Nullable private String sql; @@ -69,6 +71,7 @@ public class InvalidResultSetAccessException extends InvalidDataAccessResourceUs * Return the SQL that caused the problem. * @return the offending SQL, if known */ + @Nullable public String getSql() { return this.sql; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index 8516d684e0b..b6d58a8b39e 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -515,6 +515,7 @@ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { class BatchUpdateStatementCallback implements StatementCallback, SqlProvider { + @Nullable private String currSql; @Override diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/RowCountCallbackHandler.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/RowCountCallbackHandler.java index 3211924855f..2281489eabf 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/RowCountCallbackHandler.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/RowCountCallbackHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -21,6 +21,7 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import org.springframework.jdbc.support.JdbcUtils; +import org.springframework.lang.Nullable; /** * Implementation of RowCallbackHandler. Convenient superclass for callback handlers. @@ -54,11 +55,13 @@ public class RowCountCallbackHandler implements RowCallbackHandler { * Indexed from 0. Type (as in java.sql.Types) for the columns * as returned by ResultSetMetaData object. */ + @Nullable private int[] columnTypes; /** * Indexed from 0. Column name as returned by ResultSetMetaData object. */ + @Nullable private String[] columnNames; @@ -102,8 +105,9 @@ public class RowCountCallbackHandler implements RowCallbackHandler { * @return the types of the columns as java.sql.Types constants. * Indexed from 0 to n-1. */ + @Nullable public final int[] getColumnTypes() { - return columnTypes; + return this.columnTypes; } /** @@ -112,8 +116,9 @@ public class RowCountCallbackHandler implements RowCallbackHandler { * @return the names of the columns. * Indexed from 0 to n-1. */ + @Nullable public final String[] getColumnNames() { - return columnNames; + return this.columnNames; } /** @@ -122,7 +127,7 @@ public class RowCountCallbackHandler implements RowCallbackHandler { * @return the number of rows in this ResultSet */ public final int getRowCount() { - return rowCount; + return this.rowCount; } /** @@ -132,7 +137,7 @@ public class RowCountCallbackHandler implements RowCallbackHandler { * @return the number of columns in this result set */ public final int getColumnCount() { - return columnCount; + return this.columnCount; } } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java index c76d0a6718a..2e1bbca6c00 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java @@ -107,7 +107,7 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider { @Override public void initializeWithProcedureColumnMetaData(DatabaseMetaData databaseMetaData, @Nullable String catalogName, - @Nullable String schemaName, String procedureName) throws SQLException { + @Nullable String schemaName, @Nullable String procedureName) throws SQLException { this.procedureColumnMetaDataUsed = true; processProcedureColumns(databaseMetaData, catalogName, schemaName, procedureName); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java index f29d06bf1c8..6cf4cc8880a 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcCall.java @@ -71,12 +71,14 @@ public abstract class AbstractJdbcCall { private volatile boolean compiled = false; /** The generated string used for call statement */ + @Nullable private String callString; /** * A delegate enabling us to create CallableStatementCreators * efficiently, based on this class's declared parameters. */ + @Nullable private CallableStatementCreatorFactory callableStatementFactory; @@ -222,6 +224,7 @@ public abstract class AbstractJdbcCall { /** * Get the call string that should be used based on parameters and meta data. */ + @Nullable public String getCallString() { return this.callString; } @@ -230,6 +233,7 @@ public abstract class AbstractJdbcCall { * Get the {@link CallableStatementCreatorFactory} being used */ protected CallableStatementCreatorFactory getCallableStatementFactory() { + Assert.state(this.callableStatementFactory != null, "No CallableStatementCreatorFactory available"); return this.callableStatementFactory; } @@ -322,7 +326,7 @@ public abstract class AbstractJdbcCall { } this.callableStatementFactory = - new CallableStatementCreatorFactory(getCallString(), this.callMetaDataContext.getCallParameters()); + new CallableStatementCreatorFactory(this.callString, this.callMetaDataContext.getCallParameters()); onCompileInternal(); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java index c2ed1114530..9fc040c7287 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/AbstractJdbcInsert.java @@ -81,9 +81,11 @@ public abstract class AbstractJdbcInsert { private volatile boolean compiled = false; /** The generated string used for insert statement */ + @Nullable private String insertString; /** The SQL type information for the insert columns */ + @Nullable private int[] insertTypes; @@ -222,6 +224,7 @@ public abstract class AbstractJdbcInsert { /** * Get the insert string to be used. */ + @Nullable public String getInsertString() { return this.insertString; } @@ -229,6 +232,7 @@ public abstract class AbstractJdbcInsert { /** * Get the array of {@link java.sql.Types} to be used for insert. */ + @Nullable public int[] getInsertTypes() { return this.insertTypes; } @@ -276,7 +280,7 @@ public abstract class AbstractJdbcInsert { this.insertString = this.tableMetaDataContext.createInsertString(getGeneratedKeyNames()); this.insertTypes = this.tableMetaDataContext.createInsertTypes(); if (logger.isDebugEnabled()) { - logger.debug("Compiled insert object: insert string is [" + getInsertString() + "]"); + logger.debug("Compiled insert object: insert string is [" + this.insertString + "]"); } onCompileInternal(); } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java index a1f72bdb74c..538e97907ee 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/support/JdbcBeanDefinitionReader.java @@ -22,6 +22,7 @@ import javax.sql.DataSource; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader; import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -45,6 +46,7 @@ public class JdbcBeanDefinitionReader { private final PropertiesBeanDefinitionReader propReader; + @Nullable private JdbcTemplate jdbcTemplate; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/IsolationLevelDataSourceAdapter.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/IsolationLevelDataSourceAdapter.java index fd9e9e10c4e..5ff105a943d 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/IsolationLevelDataSourceAdapter.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/IsolationLevelDataSourceAdapter.java @@ -126,7 +126,7 @@ public class IsolationLevelDataSourceAdapter extends UserCredentialsDataSourceAd * @see #getCurrentReadOnlyFlag() */ @Override - protected Connection doGetConnection(String username, String password) throws SQLException { + protected Connection doGetConnection(@Nullable String username, @Nullable String password) throws SQLException { Connection con = super.doGetConnection(username, password); Boolean readOnlyToUse = getCurrentReadOnlyFlag(); if (readOnlyToUse != null) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java index 88a5745fd05..75dc0a50daf 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/SimpleDriverDataSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -22,6 +22,7 @@ import java.sql.SQLException; import java.util.Properties; import org.springframework.beans.BeanUtils; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -52,6 +53,7 @@ import org.springframework.util.Assert; */ public class SimpleDriverDataSource extends AbstractDriverBasedDataSource { + @Nullable private Driver driver; @@ -117,13 +119,14 @@ public class SimpleDriverDataSource extends AbstractDriverBasedDataSource { * Driver instance. * @see #setDriverClass */ - public void setDriver(Driver driver) { + public void setDriver(@Nullable Driver driver) { this.driver = driver; } /** * Return the JDBC Driver instance to use. */ + @Nullable public Driver getDriver() { return this.driver; } diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/WebSphereDataSourceAdapter.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/WebSphereDataSourceAdapter.java index c72d72bdfc1..363af595d97 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/WebSphereDataSourceAdapter.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/WebSphereDataSourceAdapter.java @@ -132,7 +132,7 @@ public class WebSphereDataSourceAdapter extends IsolationLevelDataSourceAdapter * @see com.ibm.websphere.rsadapter.WSDataSource#getConnection(com.ibm.websphere.rsadapter.JDBCConnectionSpec) */ @Override - protected Connection doGetConnection(String username, String password) throws SQLException { + protected Connection doGetConnection(@Nullable String username, @Nullable String password) throws SQLException { // Create JDBCConnectionSpec using current isolation level value and read-only flag. Object connSpec = createConnectionSpec( getCurrentIsolationLevel(), getCurrentReadOnlyFlag(), username, password); diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DataSourceInitializer.java b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DataSourceInitializer.java index 5d68d15d03a..c0d1fed11fb 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DataSourceInitializer.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/datasource/init/DataSourceInitializer.java @@ -38,8 +38,10 @@ public class DataSourceInitializer implements InitializingBean, DisposableBean { @Nullable private DataSource dataSource; + @Nullable private DatabasePopulator databasePopulator; + @Nullable private DatabasePopulator databaseCleaner; private boolean enabled = true; diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/Jdbc4SqlXmlHandler.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/Jdbc4SqlXmlHandler.java index b083f9ab191..023c0d93210 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/Jdbc4SqlXmlHandler.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/xml/Jdbc4SqlXmlHandler.java @@ -171,6 +171,7 @@ public class Jdbc4SqlXmlHandler implements SqlXmlHandler { */ private static abstract class AbstractJdbc4SqlXmlValue implements SqlXmlValue { + @Nullable private SQLXML xmlObject; @Override @@ -187,11 +188,13 @@ public class Jdbc4SqlXmlHandler implements SqlXmlHandler { @Override public void cleanup() { - try { - this.xmlObject.free(); - } - catch (SQLException ex) { - throw new DataAccessResourceFailureException("Could not free SQLXML object", ex); + if (this.xmlObject != null) { + try { + this.xmlObject.free(); + } + catch (SQLException ex) { + throw new DataAccessResourceFailureException("Could not free SQLXML object", ex); + } } } diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java index df37f90e32d..6db7a263db5 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/AbstractMessageListenerContainer.java @@ -31,7 +31,6 @@ import org.springframework.jms.support.JmsUtils; import org.springframework.jms.support.QosSettings; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; import org.springframework.util.ErrorHandler; /** @@ -506,6 +505,7 @@ public abstract class AbstractMessageListenerContainer extends AbstractJmsListen } @Override + @Nullable public QosSettings getReplyQosSettings() { return this.replyQosSettings; } @@ -514,11 +514,12 @@ public abstract class AbstractMessageListenerContainer extends AbstractJmsListen * Set the {@link MessageConverter} strategy for converting JMS Messages. * @since 4.1 */ - public void setMessageConverter(MessageConverter messageConverter) { + public void setMessageConverter(@Nullable MessageConverter messageConverter) { this.messageConverter = messageConverter; } @Override + @Nullable public MessageConverter getMessageConverter() { return this.messageConverter; } diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessageListenerAdapter.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessageListenerAdapter.java index 2d37b3713e3..9da2823f408 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessageListenerAdapter.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessageListenerAdapter.java @@ -144,7 +144,8 @@ public class MessageListenerAdapter extends AbstractAdaptableMessageListener imp * @param delegate the delegate object */ public MessageListenerAdapter(Object delegate) { - setDelegate(delegate); + Assert.notNull(delegate, "Delegate must not be null"); + this.delegate = delegate; } @@ -196,12 +197,13 @@ public class MessageListenerAdapter extends AbstractAdaptableMessageListener imp */ @Override @SuppressWarnings("unchecked") - public void onMessage(Message message, Session session) throws JMSException { + public void onMessage(Message message, @Nullable Session session) throws JMSException { // Check whether the delegate is a MessageListener impl itself. // In that case, the adapter will simply act as a pass-through. Object delegate = getDelegate(); if (delegate != this) { if (delegate instanceof SessionAwareMessageListener) { + Assert.state(session != null, "Session is required for SessionAwareMessageListener"); ((SessionAwareMessageListener) delegate).onMessage(message, session); return; } diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java index 80794092409..7440783ac11 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/adapter/MessagingMessageListenerAdapter.java @@ -28,6 +28,7 @@ import org.springframework.messaging.MessagingException; import org.springframework.messaging.core.AbstractMessageSendingTemplate; import org.springframework.messaging.handler.invocation.InvocableHandlerMethod; import org.springframework.messaging.support.MessageBuilder; +import org.springframework.util.Assert; /** * A {@link javax.jms.MessageListener} adapter that invokes a configurable @@ -49,6 +50,7 @@ import org.springframework.messaging.support.MessageBuilder; */ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageListener { + @Nullable private InvocableHandlerMethod handlerMethod; @@ -60,9 +62,14 @@ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageLis this.handlerMethod = handlerMethod; } + private InvocableHandlerMethod getHandlerMethod() { + Assert.state(this.handlerMethod != null, "No HandlerMethod set"); + return this.handlerMethod; + } + @Override - public void onMessage(javax.jms.Message jmsMessage, Session session) throws JMSException { + public void onMessage(javax.jms.Message jmsMessage, @Nullable Session session) throws JMSException { Message message = toMessagingMessage(jmsMessage); if (logger.isDebugEnabled()) { logger.debug("Processing [" + message + "]"); @@ -78,7 +85,7 @@ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageLis @Override protected Object preProcessResponse(Object result) { - MethodParameter returnType = this.handlerMethod.getReturnType(); + MethodParameter returnType = getHandlerMethod().getReturnType(); if (result instanceof Message) { return MessageBuilder.fromMessage((Message) result) .setHeader(AbstractMessageSendingTemplate.CONVERSION_HINT_HEADER, returnType).build(); @@ -101,9 +108,10 @@ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageLis * with a dedicated error message. */ @Nullable - private Object invokeHandler(javax.jms.Message jmsMessage, Session session, Message message) { + private Object invokeHandler(javax.jms.Message jmsMessage, @Nullable Session session, Message message) { + InvocableHandlerMethod handlerMethod = getHandlerMethod(); try { - return this.handlerMethod.invoke(message, jmsMessage, session); + return handlerMethod.invoke(message, jmsMessage, session); } catch (MessagingException ex) { throw new ListenerExecutionFailedException( @@ -111,15 +119,16 @@ public class MessagingMessageListenerAdapter extends AbstractAdaptableMessageLis } catch (Exception ex) { throw new ListenerExecutionFailedException("Listener method '" + - this.handlerMethod.getMethod().toGenericString() + "' threw exception", ex); + handlerMethod.getMethod().toGenericString() + "' threw exception", ex); } } private String createMessagingErrorMessage(String description) { + InvocableHandlerMethod handlerMethod = getHandlerMethod(); StringBuilder sb = new StringBuilder(description).append("\n") .append("Endpoint handler details:\n") - .append("Method [").append(this.handlerMethod.getMethod()).append("]\n") - .append("Bean [").append(this.handlerMethod.getBean()).append("]\n"); + .append("Method [").append(handlerMethod.getMethod()).append("]\n") + .append("Bean [").append(handlerMethod.getBean()).append("]\n"); return sb.toString(); } diff --git a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointFactory.java b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointFactory.java index 372ba73db35..c10d2c33182 100644 --- a/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointFactory.java +++ b/spring-jms/src/main/java/org/springframework/jms/listener/endpoint/JmsMessageEndpointFactory.java @@ -22,6 +22,8 @@ import javax.resource.ResourceException; import javax.resource.spi.UnavailableException; import org.springframework.jca.endpoint.AbstractMessageEndpointFactory; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * JMS-specific implementation of the JCA 1.7 @@ -47,6 +49,7 @@ import org.springframework.jca.endpoint.AbstractMessageEndpointFactory; */ public class JmsMessageEndpointFactory extends AbstractMessageEndpointFactory { + @Nullable private MessageListener messageListener; @@ -61,6 +64,7 @@ public class JmsMessageEndpointFactory extends AbstractMessageEndpointFactory { * Return the JMS MessageListener for this endpoint. */ protected MessageListener getMessageListener() { + Assert.state(messageListener != null, "No MessageListener set"); return this.messageListener; } @@ -90,16 +94,12 @@ public class JmsMessageEndpointFactory extends AbstractMessageEndpointFactory { } } try { - messageListener.onMessage(message); + getMessageListener().onMessage(message); } - catch (RuntimeException ex) { + catch (RuntimeException | Error ex) { onEndpointException(ex); throw ex; } - catch (Error err) { - onEndpointException(err); - throw err; - } finally { if (applyDeliveryCalls) { try { @@ -114,7 +114,7 @@ public class JmsMessageEndpointFactory extends AbstractMessageEndpointFactory { @Override protected ClassLoader getEndpointClassLoader() { - return messageListener.getClass().getClassLoader(); + return getMessageListener().getClass().getClassLoader(); } } diff --git a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java b/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java index 0f645f65e3e..7683d8cf269 100644 --- a/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java +++ b/spring-jms/src/main/java/org/springframework/jms/remoting/JmsInvokerServiceExporter.java @@ -59,6 +59,7 @@ public class JmsInvokerServiceExporter extends RemoteInvocationBasedExporter private boolean ignoreInvalidRequests = true; + @Nullable private Object proxy; diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java index 8fa6fb1e74e..5cd45005814 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -32,6 +32,7 @@ import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.springframework.beans.factory.InitializingBean; +import org.springframework.lang.Nullable; import org.springframework.oxm.Marshaller; import org.springframework.oxm.Unmarshaller; import org.springframework.oxm.XmlMappingException; @@ -51,8 +52,10 @@ import org.springframework.util.Assert; */ public class MarshallingMessageConverter implements MessageConverter, InitializingBean { + @Nullable private Marshaller marshaller; + @Nullable private Unmarshaller unmarshaller; private MessageType targetType = MessageType.BYTES; @@ -108,6 +111,7 @@ public class MarshallingMessageConverter implements MessageConverter, Initializi * Set the {@link Marshaller} to be used by this message converter. */ public void setMarshaller(Marshaller marshaller) { + Assert.notNull(marshaller, "Marshaller must not be null"); this.marshaller = marshaller; } @@ -115,6 +119,7 @@ public class MarshallingMessageConverter implements MessageConverter, Initializi * Set the {@link Unmarshaller} to be used by this message converter. */ public void setUnmarshaller(Unmarshaller unmarshaller) { + Assert.notNull(unmarshaller, "Unmarshaller must not be null"); this.unmarshaller = unmarshaller; } @@ -148,6 +153,7 @@ public class MarshallingMessageConverter implements MessageConverter, Initializi */ @Override public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException { + Assert.state(this.marshaller != null, "No Marshaller set"); try { switch (this.targetType) { case TEXT: @@ -158,10 +164,7 @@ public class MarshallingMessageConverter implements MessageConverter, Initializi return marshalToMessage(object, session, this.marshaller, this.targetType); } } - catch (XmlMappingException ex) { - throw new MessageConversionException("Could not marshal [" + object + "]", ex); - } - catch (IOException ex) { + catch (XmlMappingException | IOException ex) { throw new MessageConversionException("Could not marshal [" + object + "]", ex); } } @@ -173,6 +176,7 @@ public class MarshallingMessageConverter implements MessageConverter, Initializi */ @Override public Object fromMessage(Message message) throws JMSException, MessageConversionException { + Assert.state(this.unmarshaller != null, "No Unmarshaller set"); try { if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/DefaultContentTypeResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/DefaultContentTypeResolver.java index 7f47ffc252e..0415a72b89b 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/DefaultContentTypeResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/DefaultContentTypeResolver.java @@ -32,6 +32,7 @@ import org.springframework.util.MimeType; */ public class DefaultContentTypeResolver implements ContentTypeResolver { + @Nullable private MimeType defaultMimeType; @@ -40,7 +41,7 @@ public class DefaultContentTypeResolver implements ContentTypeResolver { * {@link MessageHeaders#CONTENT_TYPE} header present. *

This property does not have a default value. */ - public void setDefaultMimeType(MimeType defaultMimeType) { + public void setDefaultMimeType(@Nullable MimeType defaultMimeType) { this.defaultMimeType = defaultMimeType; } @@ -48,6 +49,7 @@ public class DefaultContentTypeResolver implements ContentTypeResolver { * Return the default MIME type to use if no * {@link MessageHeaders#CONTENT_TYPE} header is present. */ + @Nullable public MimeType getDefaultMimeType() { return this.defaultMimeType; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/core/GenericMessagingTemplate.java b/spring-messaging/src/main/java/org/springframework/messaging/core/GenericMessagingTemplate.java index c3a042822eb..b9905766be7 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/core/GenericMessagingTemplate.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/core/GenericMessagingTemplate.java @@ -276,6 +276,7 @@ public class GenericMessagingTemplate extends AbstractDestinationResolvingMessag private final boolean throwExceptionOnLateReply; + @Nullable private volatile Message replyMessage; private volatile boolean hasReceived; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractBrokerMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractBrokerMessageHandler.java index 62bc7ea74b5..742ad8c22f6 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractBrokerMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/AbstractBrokerMessageHandler.java @@ -283,7 +283,9 @@ public abstract class AbstractBrokerMessageHandler private class UnsentDisconnectChannelInterceptor extends ChannelInterceptorAdapter { @Override - public void afterSendCompletion(Message message, MessageChannel channel, boolean sent, Exception ex) { + public void afterSendCompletion( + Message message, MessageChannel channel, boolean sent, @Nullable Exception ex) { + if (!sent) { SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(message.getHeaders()); if (SimpMessageType.DISCONNECT.equals(messageType)) { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/DefaultStompSession.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/DefaultStompSession.java index 78de2e3572c..9e2836621df 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/DefaultStompSession.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/DefaultStompSession.java @@ -548,6 +548,7 @@ public class DefaultStompSession implements ConnectionHandlingStompSession { } @Override + @Nullable public String getReceiptId() { return this.receiptId; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaderAccessor.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaderAccessor.java index 1fc249eb14a..60df8aacde6 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaderAccessor.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompHeaderAccessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -256,7 +256,7 @@ public class StompHeaderAccessor extends SimpMessageHeaderAccessor { } @Override - public void setDestination(String destination) { + public void setDestination(@Nullable String destination) { super.setDestination(destination); setNativeHeader(STOMP_DESTINATION_HEADER, destination); } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java index c21640379e2..f76ba0c7661 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/MultiServerUserRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -18,6 +18,7 @@ package org.springframework.messaging.simp.user; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -195,9 +196,9 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati */ private static class UserRegistrySnapshot { - private String id; + private String id = ""; - private Map users; + private Map users = Collections.emptyMap(); private long expirationTime; @@ -273,12 +274,12 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati */ private static class TransferSimpUser implements SimpUser { - private String name; + private String name = ""; - /* User sessions from "this" registry only (i.e. one server) */ + // User sessions from "this" registry only (i.e. one server) private Set sessions; - /* Cross-server session lookup (e.g. user connected to multiple servers) */ + // Cross-server session lookup (e.g. user connected to multiple servers) @Nullable private SessionLookup sessionLookup; @@ -393,6 +394,8 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati */ @SuppressWarnings("unused") public TransferSimpSession() { + this.id = ""; + this.user = new TransferSimpUser(); this.subscriptions = new HashSet<>(4); } @@ -401,6 +404,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati */ public TransferSimpSession(SimpSession session) { this.id = session.getId(); + this.user = new TransferSimpUser(); Set subscriptions = session.getSubscriptions(); this.subscriptions = new HashSet<>(subscriptions.size()); for (SimpSubscription subscription : subscriptions) { @@ -443,12 +447,12 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati @Override public boolean equals(Object other) { - return (this == other || (other instanceof SimpSession && this.id.equals(((SimpSession) other).getId()))); + return (this == other || (other instanceof SimpSession && getId().equals(((SimpSession) other).getId()))); } @Override public int hashCode() { - return this.id.hashCode(); + return getId().hashCode(); } @Override @@ -474,6 +478,9 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati */ @SuppressWarnings("unused") public TransferSimpSubscription() { + this.id = ""; + this.session = new TransferSimpSession(); + this.destination = ""; } /** @@ -481,6 +488,7 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati */ public TransferSimpSubscription(SimpSubscription subscription) { this.id = subscription.getId(); + this.session = new TransferSimpSession(); this.destination = subscription.getDestination(); } @@ -520,13 +528,13 @@ public class MultiServerUserRegistry implements SimpUserRegistry, SmartApplicati return false; } SimpSubscription otherSubscription = (SimpSubscription) other; - return (ObjectUtils.nullSafeEquals(getSession(), otherSubscription.getSession()) && - this.id.equals(otherSubscription.getId())); + return (getId().equals(otherSubscription.getId()) && + ObjectUtils.nullSafeEquals(getSession(), otherSubscription.getSession())); } @Override public int hashCode() { - return this.id.hashCode() * 31 + ObjectUtils.nullSafeHashCode(getSession()); + return getId().hashCode() * 31 + ObjectUtils.nullSafeHashCode(getSession()); } @Override diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/SimpSession.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/SimpSession.java index e8642cd6403..d3b81c91da9 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/SimpSession.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/SimpSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -18,6 +18,8 @@ package org.springframework.messaging.simp.user; import java.util.Set; +import org.springframework.lang.Nullable; + /** * Represents a session of connected user. * diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/SimpSubscription.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/SimpSubscription.java index 9cb9e0ee9b5..2df8b6a9b74 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/user/SimpSubscription.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/user/SimpSubscription.java @@ -16,6 +16,8 @@ package org.springframework.messaging.simp.user; +import org.springframework.lang.Nullable; + /** * Represents a subscription within a user session. * @@ -25,17 +27,17 @@ package org.springframework.messaging.simp.user; public interface SimpSubscription { /** - * Return the id associated of the subscription (never {@code null}). + * Return the id associated of the subscription. */ String getId(); /** - * Return the session of the subscription (never {@code null}). + * Return the session of the subscription. */ SimpSession getSession(); /** - * Return the subscription's destination (never {@code null}). + * Return the subscription's destination. */ String getDestination(); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/ChannelInterceptorAdapter.java b/spring-messaging/src/main/java/org/springframework/messaging/support/ChannelInterceptorAdapter.java index 10994797a76..9258fc098df 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/ChannelInterceptorAdapter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/ChannelInterceptorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 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. @@ -16,6 +16,7 @@ package org.springframework.messaging.support; +import org.springframework.lang.Nullable; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; @@ -39,7 +40,7 @@ public abstract class ChannelInterceptorAdapter implements ChannelInterceptor { } @Override - public void afterSendCompletion(Message message, MessageChannel channel, boolean sent, Exception ex) { + public void afterSendCompletion(Message message, MessageChannel channel, boolean sent, @Nullable Exception ex) { } public boolean preReceive(MessageChannel channel) { @@ -52,7 +53,7 @@ public abstract class ChannelInterceptorAdapter implements ChannelInterceptor { } @Override - public void afterReceiveCompletion(Message message, MessageChannel channel, Exception ex) { + public void afterReceiveCompletion(@Nullable Message message, MessageChannel channel, @Nullable Exception ex) { } } diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/user/MultiServerUserRegistryTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/user/MultiServerUserRegistryTests.java index 2e93ce20834..ece661fbd7d 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/user/MultiServerUserRegistryTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/user/MultiServerUserRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -49,7 +49,7 @@ public class MultiServerUserRegistryTests { @Before - public void setUp() throws Exception { + public void setup() throws Exception { this.localRegistry = Mockito.mock(SimpUserRegistry.class); this.registry = new MultiServerUserRegistry(this.localRegistry); this.converter = new MappingJackson2MessageConverter(); @@ -70,7 +70,6 @@ public class MultiServerUserRegistryTests { @Test public void getUserFromRemoteRegistry() throws Exception { - // Prepare broadcast message from remote server TestSimpUser testUser = new TestSimpUser("joe"); TestSimpSession testSession = new TestSimpSession("remote-sess"); @@ -84,7 +83,6 @@ public class MultiServerUserRegistryTests { // Add remote registry this.registry.addRemoteRegistryDto(message, this.converter, 20000); - assertEquals(1, this.registry.getUserCount()); SimpUser user = this.registry.getUser("joe"); assertNotNull(user); @@ -103,7 +101,6 @@ public class MultiServerUserRegistryTests { @Test public void findSubscriptionsFromRemoteRegistry() throws Exception { - // Prepare broadcast message from remote server TestSimpUser user1 = new TestSimpUser("joe"); TestSimpUser user2 = new TestSimpUser("jane"); @@ -125,7 +122,6 @@ public class MultiServerUserRegistryTests { // Add remote registry this.registry.addRemoteRegistryDto(message, this.converter, 20000); - assertEquals(3, this.registry.getUserCount()); Set matches = this.registry.findSubscriptions(s -> s.getDestination().equals("/match")); assertEquals(2, matches.size()); @@ -136,9 +132,8 @@ public class MultiServerUserRegistryTests { assertEquals(new HashSet<>(Arrays.asList("sess1", "sess2")), sessionIds); } - @Test // SPR-13800 + @Test // SPR-13800 public void getSessionsWhenUserIsConnectedToMultipleServers() throws Exception { - // Add user to local registry TestSimpUser localUser = new TestSimpUser("joe"); TestSimpSession localSession = new TestSimpSession("sess123"); @@ -175,7 +170,6 @@ public class MultiServerUserRegistryTests { @Test public void purgeExpiredRegistries() throws Exception { - // Prepare broadcast message from remote server TestSimpUser testUser = new TestSimpUser("joe"); testUser.addSessions(new TestSimpSession("remote-sub")); diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java index c410837bda3..840f9559f75 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate5/support/OpenSessionInViewInterceptor.java @@ -30,6 +30,7 @@ import org.springframework.orm.hibernate5.SessionFactoryUtils; import org.springframework.orm.hibernate5.SessionHolder; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.ui.ModelMap; +import org.springframework.util.Assert; import org.springframework.web.context.request.AsyncWebRequestInterceptor; import org.springframework.web.context.request.WebRequest; import org.springframework.web.context.request.async.CallableProcessingInterceptor; @@ -79,23 +80,31 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor protected final Log logger = LogFactory.getLog(getClass()); + @Nullable private SessionFactory sessionFactory; /** * Set the Hibernate SessionFactory that should be used to create Hibernate Sessions. */ - public void setSessionFactory(SessionFactory sessionFactory) { + public void setSessionFactory(@Nullable SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } /** * Return the Hibernate SessionFactory that should be used to create Hibernate Sessions. */ + @Nullable public SessionFactory getSessionFactory() { return this.sessionFactory; } + private SessionFactory obtainSessionFactory() { + SessionFactory sf = getSessionFactory(); + Assert.state(sf != null, "No SessionFactory set"); + return sf; + } + /** * Open a new Hibernate {@code Session} according and bind it to the thread via the @@ -112,7 +121,7 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor } } - if (TransactionSynchronizationManager.hasResource(getSessionFactory())) { + if (TransactionSynchronizationManager.hasResource(obtainSessionFactory())) { // Do not modify the Session: just mark the request accordingly. Integer count = (Integer) request.getAttribute(participateAttributeName, WebRequest.SCOPE_REQUEST); int newCount = (count != null ? count + 1 : 1); @@ -122,10 +131,10 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor logger.debug("Opening Hibernate Session in OpenSessionInViewInterceptor"); Session session = openSession(); SessionHolder sessionHolder = new SessionHolder(session); - TransactionSynchronizationManager.bindResource(getSessionFactory(), sessionHolder); + TransactionSynchronizationManager.bindResource(obtainSessionFactory(), sessionHolder); AsyncRequestInterceptor asyncRequestInterceptor = - new AsyncRequestInterceptor(getSessionFactory(), sessionHolder); + new AsyncRequestInterceptor(obtainSessionFactory(), sessionHolder); asyncManager.registerCallableInterceptor(participateAttributeName, asyncRequestInterceptor); asyncManager.registerDeferredResultInterceptor(participateAttributeName, asyncRequestInterceptor); } @@ -143,7 +152,7 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor public void afterCompletion(WebRequest request, @Nullable Exception ex) throws DataAccessException { if (!decrementParticipateCount(request)) { SessionHolder sessionHolder = - (SessionHolder) TransactionSynchronizationManager.unbindResource(getSessionFactory()); + (SessionHolder) TransactionSynchronizationManager.unbindResource(obtainSessionFactory()); logger.debug("Closing Hibernate Session in OpenSessionInViewInterceptor"); SessionFactoryUtils.closeSession(sessionHolder.getSession()); } @@ -168,7 +177,7 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor @Override public void afterConcurrentHandlingStarted(WebRequest request) { if (!decrementParticipateCount(request)) { - TransactionSynchronizationManager.unbindResource(getSessionFactory()); + TransactionSynchronizationManager.unbindResource(obtainSessionFactory()); } } @@ -183,7 +192,7 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor @SuppressWarnings("deprecation") protected Session openSession() throws DataAccessResourceFailureException { try { - Session session = getSessionFactory().openSession(); + Session session = obtainSessionFactory().openSession(); session.setFlushMode(FlushMode.MANUAL); return session; } @@ -199,7 +208,7 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor * of the {@code SessionFactory} instance and appends {@link #PARTICIPATE_SUFFIX}. */ protected String getParticipateAttributeName() { - return getSessionFactory().toString() + PARTICIPATE_SUFFIX; + return obtainSessionFactory().toString() + PARTICIPATE_SUFFIX; } private boolean applySessionBindingInterceptor(WebAsyncManager asyncManager, String key) { diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java index 970cc84e662..c9e7abf1185 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/AbstractEntityManagerFactoryBean.java @@ -159,11 +159,12 @@ public abstract class AbstractEntityManagerFactoryBean implements * @see javax.persistence.spi.PersistenceProvider * @see javax.persistence.Persistence */ - public void setPersistenceProvider(PersistenceProvider persistenceProvider) { + public void setPersistenceProvider(@Nullable PersistenceProvider persistenceProvider) { this.persistenceProvider = persistenceProvider; } @Override + @Nullable public PersistenceProvider getPersistenceProvider() { return this.persistenceProvider; } @@ -175,11 +176,12 @@ public abstract class AbstractEntityManagerFactoryBean implements * ambiguous EntityManager configurations are found. * @see javax.persistence.Persistence#createEntityManagerFactory(String) */ - public void setPersistenceUnitName(String persistenceUnitName) { + public void setPersistenceUnitName(@Nullable String persistenceUnitName) { this.persistenceUnitName = persistenceUnitName; } @Override + @Nullable public String getPersistenceUnitName() { return this.persistenceUnitName; } @@ -240,11 +242,12 @@ public abstract class AbstractEntityManagerFactoryBean implements * @see JpaVendorAdapter#getEntityManagerInterface() * @see EntityManagerFactoryInfo#getEntityManagerInterface() */ - public void setEntityManagerInterface(Class emInterface) { + public void setEntityManagerInterface(@Nullable Class emInterface) { this.entityManagerInterface = emInterface; } @Override + @Nullable public Class getEntityManagerInterface() { return this.entityManagerInterface; } @@ -256,11 +259,12 @@ public abstract class AbstractEntityManagerFactoryBean implements * accessors that intend to use JpaDialect functionality. * @see EntityManagerFactoryInfo#getJpaDialect() */ - public void setJpaDialect(JpaDialect jpaDialect) { + public void setJpaDialect(@Nullable JpaDialect jpaDialect) { this.jpaDialect = jpaDialect; } @Override + @Nullable public JpaDialect getJpaDialect() { return this.jpaDialect; } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java index d1e8343040e..3b228381f03 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/DefaultJpaDialect.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -70,7 +70,7 @@ public class DefaultJpaDialect implements JpaDialect, Serializable { } @Override - public Object prepareTransaction(EntityManager entityManager, boolean readOnly, String name) + public Object prepareTransaction(EntityManager entityManager, boolean readOnly, @Nullable String name) throws PersistenceException { return null; diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java index 23c3339dc3e..ee96c8a2d86 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/LocalContainerEntityManagerFactoryBean.java @@ -140,9 +140,11 @@ public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManage * @see DefaultPersistenceUnitManager#setDefaultPersistenceUnitName */ @Override - public void setPersistenceUnitName(String persistenceUnitName) { + public void setPersistenceUnitName(@Nullable String persistenceUnitName) { super.setPersistenceUnitName(persistenceUnitName); - this.internalPersistenceUnitManager.setDefaultPersistenceUnitName(persistenceUnitName); + if (persistenceUnitName != null) { + this.internalPersistenceUnitManager.setDefaultPersistenceUnitName(persistenceUnitName); + } } /** @@ -392,6 +394,7 @@ public class LocalContainerEntityManagerFactoryBean extends AbstractEntityManage @Override + @Nullable public PersistenceUnitInfo getPersistenceUnitInfo() { return this.persistenceUnitInfo; } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java index a694d113975..89dc9f6d8ff 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/persistenceunit/SpringPersistenceUnitInfo.java @@ -69,6 +69,7 @@ class SpringPersistenceUnitInfo extends MutablePersistenceUnitInfo { * if specified. */ @Override + @Nullable public ClassLoader getClassLoader() { return this.classLoader; } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java index c7befaccb8b..1d573433f4a 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/HibernateJpaDialect.java @@ -169,7 +169,7 @@ public class HibernateJpaDialect extends DefaultJpaDialect { } @Override - public Object prepareTransaction(EntityManager entityManager, boolean readOnly, String name) + public Object prepareTransaction(EntityManager entityManager, boolean readOnly, @Nullable String name) throws PersistenceException { Session session = getSession(entityManager); diff --git a/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java b/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java index fedb569971e..548023d2ec2 100644 --- a/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java @@ -37,6 +37,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpRange; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.AbstractServerHttpRequest; +import org.springframework.lang.Nullable; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MimeType; import org.springframework.util.MultiValueMap; @@ -58,15 +59,15 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest { private final MultiValueMap cookies; + @Nullable private final InetSocketAddress remoteAddress; private final Flux body; - private MockServerHttpRequest(HttpMethod httpMethod, URI uri, String contextPath, + private MockServerHttpRequest(HttpMethod httpMethod, URI uri, @Nullable String contextPath, HttpHeaders headers, MultiValueMap cookies, - InetSocketAddress remoteAddress, - Publisher body) { + @Nullable InetSocketAddress remoteAddress, Publisher body) { super(uri, contextPath, headers); this.httpMethod = httpMethod; @@ -87,6 +88,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest { } @Override + @Nullable public InetSocketAddress getRemoteAddress() { return this.remoteAddress; } @@ -351,20 +353,20 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest { private static final DataBufferFactory BUFFER_FACTORY = new DefaultDataBufferFactory(); - private final HttpMethod method; private final URI url; + @Nullable private String contextPath; private final HttpHeaders headers = new HttpHeaders(); private final MultiValueMap cookies = new LinkedMultiValueMap<>(); + @Nullable private InetSocketAddress remoteAddress; - public DefaultBodyBuilder(HttpMethod method, URI url) { this.method = method; this.url = url; diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java b/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java index 8335c2db8d7..576e7f64f60 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java @@ -18,6 +18,8 @@ package org.springframework.mock.web; import javax.servlet.SessionCookieConfig; +import org.springframework.lang.Nullable; + /** * Mock implementation of the {@link javax.servlet.SessionCookieConfig} interface. * @@ -27,12 +29,16 @@ import javax.servlet.SessionCookieConfig; */ public class MockSessionCookieConfig implements SessionCookieConfig { + @Nullable private String name; + @Nullable private String domain; + @Nullable private String path; + @Nullable private String comment; private boolean httpOnly; @@ -43,41 +49,45 @@ public class MockSessionCookieConfig implements SessionCookieConfig { @Override - public void setName(String name) { + public void setName(@Nullable String name) { this.name = name; } @Override + @Nullable public String getName() { return this.name; } @Override - public void setDomain(String domain) { + public void setDomain(@Nullable String domain) { this.domain = domain; } @Override + @Nullable public String getDomain() { return this.domain; } @Override - public void setPath(String path) { + public void setPath(@Nullable String path) { this.path = path; } @Override + @Nullable public String getPath() { return this.path; } @Override - public void setComment(String comment) { + public void setComment(@Nullable String comment) { this.comment = comment; } @Override + @Nullable public String getComment() { return this.comment; } diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java b/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java index 474aef2c14d..21ed9b2322d 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractJUnit4SpringContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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,6 +23,7 @@ import org.junit.runner.RunWith; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestContext; import org.springframework.test.context.TestContextManager; @@ -99,6 +100,7 @@ public abstract class AbstractJUnit4SpringContextTests implements ApplicationCon * The {@link ApplicationContext} that was injected into this test instance * via {@link #setApplicationContext(ApplicationContext)}. */ + @Nullable protected ApplicationContext applicationContext; diff --git a/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java b/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java index 2d9fd723b29..2210f20ef76 100644 --- a/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java +++ b/spring-test/src/main/java/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.java @@ -24,6 +24,7 @@ import org.springframework.core.io.Resource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.lang.Nullable; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener; @@ -100,8 +101,9 @@ public abstract class AbstractTransactionalJUnit4SpringContextTests extends Abst * The {@code JdbcTemplate} that this base class manages, available to subclasses. * @since 3.2 */ - protected JdbcTemplate jdbcTemplate; + protected final JdbcTemplate jdbcTemplate = new JdbcTemplate(); + @Nullable private String sqlScriptEncoding; @@ -111,7 +113,7 @@ public abstract class AbstractTransactionalJUnit4SpringContextTests extends Abst */ @Autowired public void setDataSource(DataSource dataSource) { - this.jdbcTemplate = new JdbcTemplate(dataSource); + this.jdbcTemplate.setDataSource(dataSource); } /** @@ -204,6 +206,7 @@ public abstract class AbstractTransactionalJUnit4SpringContextTests extends Abst protected void executeSqlScript(String sqlResourcePath, boolean continueOnError) throws DataAccessException { DataSource ds = this.jdbcTemplate.getDataSource(); Assert.state(ds != null, "No DataSource set"); + Assert.state(this.applicationContext != null, "No ApplicationContext set"); Resource resource = this.applicationContext.getResource(sqlResourcePath); new ResourceDatabasePopulator(continueOnError, false, this.sqlScriptEncoding, resource).execute(ds); } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java index 7291d1c6f79..71cb8b9edc5 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AbstractTestContextBootstrapper.java @@ -80,22 +80,18 @@ public abstract class AbstractTestContextBootstrapper implements TestContextBoot private final Log logger = LogFactory.getLog(getClass()); + @Nullable private BootstrapContext bootstrapContext; - /** - * {@inheritDoc} - */ @Override public void setBootstrapContext(BootstrapContext bootstrapContext) { this.bootstrapContext = bootstrapContext; } - /** - * {@inheritDoc} - */ @Override public BootstrapContext getBootstrapContext() { + Assert.state(this.bootstrapContext != null, "No BootstrapContext set"); return this.bootstrapContext; } diff --git a/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTransactionalTestNGSpringContextTests.java b/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTransactionalTestNGSpringContextTests.java index 79a71470999..a0559717814 100644 --- a/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTransactionalTestNGSpringContextTests.java +++ b/spring-test/src/main/java/org/springframework/test/context/testng/AbstractTransactionalTestNGSpringContextTests.java @@ -24,6 +24,7 @@ import org.springframework.core.io.Resource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.lang.Nullable; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener; import org.springframework.test.context.transaction.TransactionalTestExecutionListener; @@ -84,8 +85,9 @@ public abstract class AbstractTransactionalTestNGSpringContextTests extends Abst * The {@code JdbcTemplate} that this base class manages, available to subclasses. * @since 3.2 */ - protected JdbcTemplate jdbcTemplate; + protected final JdbcTemplate jdbcTemplate = new JdbcTemplate(); + @Nullable private String sqlScriptEncoding; @@ -95,7 +97,7 @@ public abstract class AbstractTransactionalTestNGSpringContextTests extends Abst */ @Autowired public void setDataSource(DataSource dataSource) { - this.jdbcTemplate = new JdbcTemplate(dataSource); + this.jdbcTemplate.setDataSource(dataSource); } /** diff --git a/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java b/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java index 33bdb21b608..6f17e6402a5 100644 --- a/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java +++ b/spring-test/src/main/java/org/springframework/test/context/web/WebMergedContextConfiguration.java @@ -166,7 +166,7 @@ public class WebMergedContextConfiguration extends MergedContextConfiguration { * {@link #getContextLoader() ContextLoaders}. */ @Override - public boolean equals(Object other) { + public boolean equals(@Nullable Object other) { return (this == other || (super.equals(other) && this.resourceBasePath.equals(((WebMergedContextConfiguration) other).resourceBasePath))); } diff --git a/spring-test/src/main/java/org/springframework/test/web/client/DefaultRequestExpectation.java b/spring-test/src/main/java/org/springframework/test/web/client/DefaultRequestExpectation.java index cc1ef72329a..8829db7678b 100644 --- a/spring-test/src/main/java/org/springframework/test/web/client/DefaultRequestExpectation.java +++ b/spring-test/src/main/java/org/springframework/test/web/client/DefaultRequestExpectation.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -38,6 +38,7 @@ public class DefaultRequestExpectation implements RequestExpectation { private final List requestMatchers = new LinkedList<>(); + @Nullable private ResponseCreator responseCreator; diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/WebConnectionHtmlUnitDriver.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/WebConnectionHtmlUnitDriver.java index e8fc5f18443..42395489322 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/WebConnectionHtmlUnitDriver.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/webdriver/WebConnectionHtmlUnitDriver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -22,6 +22,7 @@ import com.gargoylesoftware.htmlunit.WebConnection; import org.openqa.selenium.Capabilities; import org.openqa.selenium.htmlunit.HtmlUnitDriver; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -39,6 +40,7 @@ import org.springframework.util.Assert; */ public class WebConnectionHtmlUnitDriver extends HtmlUnitDriver { + @Nullable private WebClient webClient; @@ -92,16 +94,17 @@ public class WebConnectionHtmlUnitDriver extends HtmlUnitDriver { * @since 4.3 */ public WebClient getWebClient() { + Assert.state(this.webClient != null, "No WebClient set"); return this.webClient; } /** * Set the {@link WebConnection} to be used with the {@link WebClient}. - * @param webConnection the {@code WebConnection} to use (never {@code null}) + * @param webConnection the {@code WebConnection} to use */ public void setWebConnection(WebConnection webConnection) { Assert.notNull(webConnection, "WebConnection must not be null"); - this.webClient.setWebConnection(webConnection); + getWebClient().setWebConnection(webConnection); } /** @@ -109,7 +112,7 @@ public class WebConnectionHtmlUnitDriver extends HtmlUnitDriver { * @return the current {@code WebConnection} */ public WebConnection getWebConnection() { - return this.webClient.getWebConnection(); + return getWebClient().getWebConnection(); } } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java b/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java index bb77f4e1664..3c3fea3fe2d 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/result/JsonPathResultMatchers.java @@ -23,6 +23,7 @@ import org.hamcrest.Matcher; import org.hamcrest.MatcherAssert; import org.hamcrest.core.StringStartsWith; +import org.springframework.lang.Nullable; import org.springframework.test.util.JsonPathExpectationsHelper; import org.springframework.test.web.servlet.MvcResult; import org.springframework.test.web.servlet.ResultMatcher; @@ -46,6 +47,7 @@ public class JsonPathResultMatchers { private final JsonPathExpectationsHelper jsonPathHelper; + @Nullable private String prefix; diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/RequestContextHolderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/RequestContextHolderTests.java index 0ec33e0419c..538d529ac5e 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/RequestContextHolderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/RequestContextHolderTests.java @@ -42,6 +42,7 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.annotation.RequestScope; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; @@ -161,6 +162,7 @@ public class RequestContextHolderTests { } @Bean + @RequestScope @Scope(scopeName = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) public RequestScopedService requestScopedService() { return new RequestScopedService(); diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java b/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java index 9b35ec87c74..5fb01f459a3 100644 --- a/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java +++ b/spring-tx/src/main/java/org/springframework/jca/cci/connection/ConnectionSpecConnectionFactoryAdapter.java @@ -68,6 +68,7 @@ import org.springframework.util.Assert; @SuppressWarnings("serial") public class ConnectionSpecConnectionFactoryAdapter extends DelegatingConnectionFactory { + @Nullable private ConnectionSpec connectionSpec; private final ThreadLocal threadBoundSpec = diff --git a/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CommAreaRecord.java b/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CommAreaRecord.java index a26a7756d19..4ef83494000 100644 --- a/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CommAreaRecord.java +++ b/spring-tx/src/main/java/org/springframework/jca/cci/core/support/CommAreaRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -35,11 +35,11 @@ import org.springframework.util.FileCopyUtils; @SuppressWarnings("serial") public class CommAreaRecord implements Record, Streamable { - private byte[] bytes; + private byte[] bytes = new byte[0]; - private String recordName; + private String recordName = ""; - private String recordShortDescription; + private String recordShortDescription = ""; /** @@ -60,22 +60,22 @@ public class CommAreaRecord implements Record, Streamable { @Override public void setRecordName(String recordName) { - this.recordName=recordName; + this.recordName = recordName; } @Override public String getRecordName() { - return recordName; + return this.recordName; } @Override public void setRecordShortDescription(String recordShortDescription) { - this.recordShortDescription=recordShortDescription; + this.recordShortDescription = recordShortDescription; } @Override public String getRecordShortDescription() { - return recordShortDescription; + return this.recordShortDescription; } diff --git a/spring-tx/src/main/java/org/springframework/jca/context/SpringContextResourceAdapter.java b/spring-tx/src/main/java/org/springframework/jca/context/SpringContextResourceAdapter.java index dfd5a26e115..7df12efcf8e 100644 --- a/spring-tx/src/main/java/org/springframework/jca/context/SpringContextResourceAdapter.java +++ b/spring-tx/src/main/java/org/springframework/jca/context/SpringContextResourceAdapter.java @@ -122,6 +122,7 @@ public class SpringContextResourceAdapter implements ResourceAdapter { private String contextConfigLocation = DEFAULT_CONTEXT_CONFIG_LOCATION; + @Nullable private ConfigurableApplicationContext applicationContext; @@ -208,7 +209,9 @@ public class SpringContextResourceAdapter implements ResourceAdapter { @Override public void stop() { logger.info("Stopping SpringContextResourceAdapter"); - this.applicationContext.close(); + if (this.applicationContext != null) { + this.applicationContext.close(); + } } diff --git a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointFactory.java b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointFactory.java index 41c826ff6e3..e7d55bc4f34 100644 --- a/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointFactory.java +++ b/spring-tx/src/main/java/org/springframework/jca/endpoint/GenericMessageEndpointFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -26,6 +26,8 @@ import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DelegatingIntroductionInterceptor; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; /** @@ -52,6 +54,7 @@ import org.springframework.util.ReflectionUtils; */ public class GenericMessageEndpointFactory extends AbstractMessageEndpointFactory { + @Nullable private Object messageListener; @@ -64,6 +67,15 @@ public class GenericMessageEndpointFactory extends AbstractMessageEndpointFactor this.messageListener = messageListener; } + /** + * Return the message listener object for this endpoint. + * @since 5.0 + */ + protected Object getMessageListener() { + Assert.state(this.messageListener != null, "No message listener set"); + return this.messageListener; + } + /** * Wrap each concrete endpoint instance with an AOP proxy, * exposing the message listener's interfaces as well as the @@ -72,7 +84,7 @@ public class GenericMessageEndpointFactory extends AbstractMessageEndpointFactor @Override public MessageEndpoint createEndpoint(XAResource xaResource) throws UnavailableException { GenericMessageEndpoint endpoint = (GenericMessageEndpoint) super.createEndpoint(xaResource); - ProxyFactory proxyFactory = new ProxyFactory(this.messageListener); + ProxyFactory proxyFactory = new ProxyFactory(getMessageListener()); DelegatingIntroductionInterceptor introduction = new DelegatingIntroductionInterceptor(endpoint); introduction.suppressInterface(MethodInterceptor.class); proxyFactory.addAdvice(introduction); @@ -136,7 +148,7 @@ public class GenericMessageEndpointFactory extends AbstractMessageEndpointFactor @Override protected ClassLoader getEndpointClassLoader() { - return messageListener.getClass().getClassLoader(); + return getMessageListener().getClass().getClassLoader(); } } diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/BeanFactoryTransactionAttributeSourceAdvisor.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/BeanFactoryTransactionAttributeSourceAdvisor.java index 49da42fb873..ba034b064f1 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/BeanFactoryTransactionAttributeSourceAdvisor.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/BeanFactoryTransactionAttributeSourceAdvisor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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,6 +19,7 @@ package org.springframework.transaction.interceptor; import org.springframework.aop.ClassFilter; import org.springframework.aop.Pointcut; import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor; +import org.springframework.lang.Nullable; /** * Advisor driven by a {@link TransactionAttributeSource}, used to include @@ -33,6 +34,7 @@ import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor; @SuppressWarnings("serial") public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor { + @Nullable private TransactionAttributeSource transactionAttributeSource; private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() { diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java index dfffff5a6fa..ed2c5cb3aa1 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/DefaultTransactionAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -91,6 +91,7 @@ public class DefaultTransactionAttribute extends DefaultTransactionDefinition im * @since 3.0 */ @Override + @Nullable public String getQualifier() { return this.qualifier; } diff --git a/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java b/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java index 56bd8f8aa6c..91c87960cdf 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java +++ b/spring-tx/src/main/java/org/springframework/transaction/support/DefaultTransactionDefinition.java @@ -216,6 +216,7 @@ public class DefaultTransactionDefinition implements TransactionDefinition, Seri } @Override + @Nullable public final String getName() { return this.name; } diff --git a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java index 38e3c1d147f..b459e3a147a 100644 --- a/spring-web/src/main/java/org/springframework/http/ResponseCookie.java +++ b/spring-web/src/main/java/org/springframework/http/ResponseCookie.java @@ -36,8 +36,10 @@ public final class ResponseCookie extends HttpCookie { private final Duration maxAge; + @Nullable private final String domain; + @Nullable private final String path; private final boolean secure; @@ -48,8 +50,8 @@ public final class ResponseCookie extends HttpCookie { /** * Private constructor. See {@link #from(String, String)}. */ - private ResponseCookie(String name, String value, Duration maxAge, String domain, - String path, boolean secure, boolean httpOnly) { + private ResponseCookie(String name, String value, Duration maxAge, @Nullable String domain, + @Nullable String path, boolean secure, boolean httpOnly) { super(name, value); Assert.notNull(maxAge, "Max age must not be null"); @@ -168,8 +170,10 @@ public final class ResponseCookie extends HttpCookie { private Duration maxAge = Duration.ofSeconds(-1); + @Nullable private String domain; + @Nullable private String path; private boolean secure; diff --git a/spring-web/src/main/java/org/springframework/http/client/support/AsyncHttpAccessor.java b/spring-web/src/main/java/org/springframework/http/client/support/AsyncHttpAccessor.java index 99a0b0ed69e..0683ad1b1d2 100644 --- a/spring-web/src/main/java/org/springframework/http/client/support/AsyncHttpAccessor.java +++ b/spring-web/src/main/java/org/springframework/http/client/support/AsyncHttpAccessor.java @@ -23,6 +23,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpMethod; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -44,14 +45,16 @@ public class AsyncHttpAccessor { /** Logger available to subclasses. */ protected final Log logger = LogFactory.getLog(getClass()); + @Nullable private org.springframework.http.client.AsyncClientHttpRequestFactory asyncRequestFactory; + /** * Set the request factory that this accessor uses for obtaining {@link * org.springframework.http.client.ClientHttpRequest HttpRequests}. */ public void setAsyncRequestFactory(org.springframework.http.client.AsyncClientHttpRequestFactory asyncRequestFactory) { - Assert.notNull(asyncRequestFactory, "'asyncRequestFactory' must not be null"); + Assert.notNull(asyncRequestFactory, "AsyncClientHttpRequestFactory must not be null"); this.asyncRequestFactory = asyncRequestFactory; } @@ -60,6 +63,7 @@ public class AsyncHttpAccessor { * org.springframework.http.client.ClientHttpRequest HttpRequests}. */ public org.springframework.http.client.AsyncClientHttpRequestFactory getAsyncRequestFactory() { + Assert.state(asyncRequestFactory != null, "No AsyncClientHttpRequestFactory set"); return this.asyncRequestFactory; } @@ -73,7 +77,9 @@ public class AsyncHttpAccessor { */ protected org.springframework.http.client.AsyncClientHttpRequest createAsyncRequest(URI url, HttpMethod method) throws IOException { - org.springframework.http.client.AsyncClientHttpRequest request = getAsyncRequestFactory().createAsyncRequest(url, method); + + org.springframework.http.client.AsyncClientHttpRequest request = + getAsyncRequestFactory().createAsyncRequest(url, method); if (logger.isDebugEnabled()) { logger.debug("Created asynchronous " + method.name() + " request for \"" + url + "\""); } diff --git a/spring-web/src/main/java/org/springframework/http/client/support/ProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/http/client/support/ProxyFactoryBean.java index f19b7df9430..2029ab409dd 100644 --- a/spring-web/src/main/java/org/springframework/http/client/support/ProxyFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/http/client/support/ProxyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -22,6 +22,7 @@ import java.net.SocketAddress; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -36,10 +37,12 @@ public class ProxyFactoryBean implements FactoryBean, InitializingBean { private Proxy.Type type = Proxy.Type.HTTP; + @Nullable private String hostname; private int port = -1; + @Nullable private Proxy proxy; @@ -68,10 +71,10 @@ public class ProxyFactoryBean implements FactoryBean, InitializingBean { @Override public void afterPropertiesSet() throws IllegalArgumentException { - Assert.notNull(this.type, "'type' must not be null"); - Assert.hasLength(this.hostname, "'hostname' must not be empty"); + Assert.notNull(this.type, "Property 'type' is required"); + Assert.notNull(this.hostname, "Property 'hostname' is required"); if (this.port < 0 || this.port > 65535) { - throw new IllegalArgumentException("'port' value out of range: " + this.port); + throw new IllegalArgumentException("Property 'port' value out of range: " + this.port); } SocketAddress socketAddress = new InetSocketAddress(this.hostname, this.port); diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java index 76f9730bf05..90ed50eaf0a 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlDecoder.java @@ -198,6 +198,7 @@ public class Jaxb2XmlDecoder extends AbstractDecoder { private final QName desiredName; + @Nullable private List events; private int elementDepth = 0; diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/GsonHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/GsonHttpMessageConverter.java index f8362eb0361..ecf782f0746 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/GsonHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/GsonHttpMessageConverter.java @@ -52,7 +52,7 @@ public class GsonHttpMessageConverter extends AbstractJsonHttpMessageConverter { * Construct a new {@code GsonHttpMessageConverter} with default configuration. */ public GsonHttpMessageConverter() { - this(new Gson()); + this.gson = new Gson(); } /** @@ -61,7 +61,8 @@ public class GsonHttpMessageConverter extends AbstractJsonHttpMessageConverter { * @since 5.0 */ public GsonHttpMessageConverter(Gson gson) { - setGson(gson); + Assert.notNull(gson, "A Gson instance is required"); + this.gson = gson; } diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/JsonbHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/json/JsonbHttpMessageConverter.java index 5dfaf0fb8aa..3d9e5101988 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/JsonbHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/JsonbHttpMessageConverter.java @@ -58,7 +58,7 @@ public class JsonbHttpMessageConverter extends AbstractJsonHttpMessageConverter * @param config the {@code JsonbConfig} for the underlying delegate */ public JsonbHttpMessageConverter(JsonbConfig config) { - this(JsonbBuilder.create(config)); + this.jsonb = JsonbBuilder.create(config); } /** @@ -66,7 +66,8 @@ public class JsonbHttpMessageConverter extends AbstractJsonHttpMessageConverter * @param jsonb the Jsonb instance to use */ public JsonbHttpMessageConverter(Jsonb jsonb) { - setJsonb(jsonb); + Assert.notNull(jsonb, "A Jsonb instance is required"); + this.jsonb = jsonb; } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java index 00e86b9c2a5..a4ed400f9c2 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpRequest.java @@ -59,7 +59,7 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest { * @param contextPath the context path for the request * @param headers the headers for the request */ - public AbstractServerHttpRequest(URI uri, String contextPath, HttpHeaders headers) { + public AbstractServerHttpRequest(URI uri, @Nullable String contextPath, HttpHeaders headers) { this.uri = uri; this.path = RequestPath.parse(uri, contextPath); this.headers = HttpHeaders.readOnlyHttpHeaders(headers); diff --git a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java index f446a4ba7fd..d3dbe282331 100644 --- a/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/remoting/caucho/HessianProxyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2017 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. @@ -18,6 +18,7 @@ package org.springframework.remoting.caucho; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.FactoryBean; +import org.springframework.lang.Nullable; /** * {@link FactoryBean} for Hessian proxies. Exposes the proxied service @@ -42,6 +43,7 @@ import org.springframework.beans.factory.FactoryBean; */ public class HessianProxyFactoryBean extends HessianClientInterceptor implements FactoryBean { + @Nullable private Object serviceProxy; diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java index 5cef885997a..3a853c53727 100644 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java +++ b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/AbstractHttpInvokerRequestExecutor.java @@ -76,6 +76,7 @@ public abstract class AbstractHttpInvokerRequestExecutor implements HttpInvokerR private boolean acceptGzipEncoding = true; + @Nullable private ClassLoader beanClassLoader; @@ -121,6 +122,7 @@ public abstract class AbstractHttpInvokerRequestExecutor implements HttpInvokerR /** * Return the bean ClassLoader that this executor is supposed to use. */ + @Nullable protected ClassLoader getBeanClassLoader() { return this.beanClassLoader; } diff --git a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java index 9e5f61be9ec..224a4a81590 100644 --- a/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/remoting/httpinvoker/HttpInvokerProxyFactoryBean.java @@ -18,6 +18,7 @@ package org.springframework.remoting.httpinvoker; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.FactoryBean; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -55,6 +56,7 @@ import org.springframework.util.Assert; */ public class HttpInvokerProxyFactoryBean extends HttpInvokerClientInterceptor implements FactoryBean { + @Nullable private Object serviceProxy; diff --git a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java b/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java index 10952434d8f..97ec0fa2ee1 100644 --- a/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/remoting/jaxws/JaxWsPortProxyFactoryBean.java @@ -20,6 +20,7 @@ import javax.xml.ws.BindingProvider; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.FactoryBean; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -34,6 +35,7 @@ import org.springframework.util.Assert; */ public class JaxWsPortProxyFactoryBean extends JaxWsPortClientInterceptor implements FactoryBean { + @Nullable private Object serviceProxy; diff --git a/spring-web/src/main/java/org/springframework/web/HttpSessionRequiredException.java b/spring-web/src/main/java/org/springframework/web/HttpSessionRequiredException.java index 7b5f1d3bf0b..e5a5119801a 100644 --- a/spring-web/src/main/java/org/springframework/web/HttpSessionRequiredException.java +++ b/spring-web/src/main/java/org/springframework/web/HttpSessionRequiredException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -29,6 +29,7 @@ import org.springframework.lang.Nullable; @SuppressWarnings("serial") public class HttpSessionRequiredException extends ServletException { + @Nullable private String expectedAttribute; diff --git a/spring-web/src/main/java/org/springframework/web/bind/support/SessionAttributeStore.java b/spring-web/src/main/java/org/springframework/web/bind/support/SessionAttributeStore.java index d74f40f52a1..5fe836bd92d 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/support/SessionAttributeStore.java +++ b/spring-web/src/main/java/org/springframework/web/bind/support/SessionAttributeStore.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -36,7 +36,7 @@ public interface SessionAttributeStore { * @param attributeName the name of the attribute * @param attributeValue the attribute value to store */ - void storeAttribute(WebRequest request, String attributeName, @Nullable Object attributeValue); + void storeAttribute(WebRequest request, String attributeName, Object attributeValue); /** * Retrieve the specified attribute from the backend session. diff --git a/spring-web/src/main/java/org/springframework/web/client/ExtractingResponseErrorHandler.java b/spring-web/src/main/java/org/springframework/web/client/ExtractingResponseErrorHandler.java index 074c2cd41c3..f26e32aa91a 100644 --- a/spring-web/src/main/java/org/springframework/web/client/ExtractingResponseErrorHandler.java +++ b/spring-web/src/main/java/org/springframework/web/client/ExtractingResponseErrorHandler.java @@ -17,21 +17,21 @@ package org.springframework.web.client; import java.io.IOException; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.springframework.beans.factory.InitializingBean; import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.lang.Nullable; -import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; /** * Implementation of {@link ResponseErrorHandler} that uses {@link HttpMessageConverter}s to * convert HTTP error responses to {@link RestClientException}. + * *

To use this error handler, you must specify a * {@linkplain #setStatusMapping(Map) status mapping} and/or a * {@linkplain #setSeriesMapping(Map) series mapping}. If either of these mappings has a match @@ -42,6 +42,7 @@ import org.springframework.util.CollectionUtils; * into the mapped subclass of {@link RestClientException}. Note that the * {@linkplain #setStatusMapping(Map) status mapping} takes precedence over * {@linkplain #setSeriesMapping(Map) series mapping}. + * *

If there is no match, this error handler will default to the behavior of * {@link DefaultResponseErrorHandler}. Note that you can override this default behavior by * specifying a {@linkplain #setSeriesMapping(Map) series mapping} from @@ -50,19 +51,17 @@ import org.springframework.util.CollectionUtils; * * @author Simon Galperin * @author Arjen Poutsma - * @see RestTemplate#setErrorHandler(ResponseErrorHandler) * @since 5.0 + * @see RestTemplate#setErrorHandler(ResponseErrorHandler) */ -public class ExtractingResponseErrorHandler extends DefaultResponseErrorHandler - implements InitializingBean { +public class ExtractingResponseErrorHandler extends DefaultResponseErrorHandler { - private List> messageConverters; + private List> messageConverters = Collections.emptyList(); - private final Map> statusMapping = - new LinkedHashMap<>(); + private final Map> statusMapping = new LinkedHashMap<>(); + + private final Map> seriesMapping = new LinkedHashMap<>(); - private final Map> seriesMapping = - new LinkedHashMap<>(); /** * Create a new, empty {@code ExtractingResponseErrorHandler}. @@ -77,11 +76,12 @@ public class ExtractingResponseErrorHandler extends DefaultResponseErrorHandler * @param messageConverters the message converters to use */ public ExtractingResponseErrorHandler(List> messageConverters) { - setMessageConverters(messageConverters); + this.messageConverters = messageConverters; } + /** - * Sets the message converters to use by this extractor. + * Set the message converters to use by this extractor. */ public void setMessageConverters(List> messageConverters) { this.messageConverters = messageConverters; @@ -96,8 +96,7 @@ public class ExtractingResponseErrorHandler extends DefaultResponseErrorHandler * {@linkplain #setMessageConverters(List) configured message converters} to convert the * response into the mapped subclass of {@link RestClientException}. */ - public void setStatusMapping( - Map> statusMapping) { + public void setStatusMapping(Map> statusMapping) { if (!CollectionUtils.isEmpty(statusMapping)) { this.statusMapping.putAll(statusMapping); } @@ -112,17 +111,12 @@ public class ExtractingResponseErrorHandler extends DefaultResponseErrorHandler * {@linkplain #setMessageConverters(List) configured message converters} to convert the * response into the mapped subclass of {@link RestClientException}. */ - public void setSeriesMapping( - Map> seriesMapping) { + public void setSeriesMapping(Map> seriesMapping) { if (!CollectionUtils.isEmpty(seriesMapping)) { this.seriesMapping.putAll(seriesMapping); } } - @Override - public void afterPropertiesSet() throws Exception { - Assert.notEmpty(this.messageConverters, "'messageConverters' is required"); - } @Override protected boolean hasError(HttpStatus statusCode) { @@ -157,6 +151,7 @@ public class ExtractingResponseErrorHandler extends DefaultResponseErrorHandler if (exceptionClass == null) { return; } + HttpMessageConverterExtractor extractor = new HttpMessageConverterExtractor<>(exceptionClass, this.messageConverters); RestClientException exception = extractor.extractData(response); @@ -164,4 +159,5 @@ public class ExtractingResponseErrorHandler extends DefaultResponseErrorHandler throw exception; } } + } diff --git a/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java b/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java index 16ae988665e..3ec58cc9373 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/HttpRequestHandlerServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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,6 +23,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.HttpRequestHandler; import org.springframework.web.HttpRequestMethodNotSupportedException; @@ -48,6 +50,7 @@ import org.springframework.web.context.WebApplicationContext; @SuppressWarnings("serial") public class HttpRequestHandlerServlet extends HttpServlet { + @Nullable private HttpRequestHandler target; @@ -62,6 +65,8 @@ public class HttpRequestHandlerServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + Assert.state(this.target != null, "No HttpRequestHandler available"); + LocaleContextHolder.setLocale(request.getLocale()); try { this.target.handleRequest(request, response); diff --git a/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java b/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java index 702d87ee01e..90623795eef 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/LiveBeansViewServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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,6 +23,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.context.support.LiveBeansView; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; /** * Servlet variant of {@link LiveBeansView}'s MBean exposure. @@ -37,8 +39,10 @@ import org.springframework.context.support.LiveBeansView; @SuppressWarnings("serial") public class LiveBeansViewServlet extends HttpServlet { + @Nullable private LiveBeansView liveBeansView; + @Override public void init() throws ServletException { this.liveBeansView = buildLiveBeansView(); @@ -48,8 +52,12 @@ public class LiveBeansViewServlet extends HttpServlet { return new ServletContextLiveBeansView(getServletContext()); } + @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + Assert.state(this.liveBeansView != null, "No LiveBeanViews available"); String content = this.liveBeansView.getSnapshotAsJson(); response.setContentType("application/json"); response.setContentLength(content.length()); diff --git a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeExporter.java b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeExporter.java index 6c5427058f3..befbe64cb61 100644 --- a/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeExporter.java +++ b/spring-web/src/main/java/org/springframework/web/context/support/ServletContextAttributeExporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -22,6 +22,7 @@ import javax.servlet.ServletContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.lang.Nullable; import org.springframework.web.context.ServletContextAware; /** @@ -48,6 +49,7 @@ public class ServletContextAttributeExporter implements ServletContextAware { protected final Log logger = LogFactory.getLog(getClass()); + @Nullable private Map attributes; @@ -65,16 +67,18 @@ public class ServletContextAttributeExporter implements ServletContextAware { @Override public void setServletContext(ServletContext servletContext) { - for (Map.Entry entry : attributes.entrySet()) { - String attributeName = entry.getKey(); - if (logger.isWarnEnabled()) { - if (servletContext.getAttribute(attributeName) != null) { - logger.warn("Replacing existing ServletContext attribute with name '" + attributeName + "'"); + if (this.attributes != null) { + for (Map.Entry entry : this.attributes.entrySet()) { + String attributeName = entry.getKey(); + if (logger.isWarnEnabled()) { + if (servletContext.getAttribute(attributeName) != null) { + logger.warn("Replacing existing ServletContext attribute with name '" + attributeName + "'"); + } + } + servletContext.setAttribute(attributeName, entry.getValue()); + if (logger.isInfoEnabled()) { + logger.info("Exported ServletContext attribute with name '" + attributeName + "'"); } - } - servletContext.setAttribute(attributeName, entry.getValue()); - if (logger.isInfoEnabled()) { - logger.info("Exported ServletContext attribute with name '" + attributeName + "'"); } } } diff --git a/spring-web/src/main/java/org/springframework/web/jsf/DelegatingNavigationHandlerProxy.java b/spring-web/src/main/java/org/springframework/web/jsf/DelegatingNavigationHandlerProxy.java index 3a665593dc1..cd83c19589e 100644 --- a/spring-web/src/main/java/org/springframework/web/jsf/DelegatingNavigationHandlerProxy.java +++ b/spring-web/src/main/java/org/springframework/web/jsf/DelegatingNavigationHandlerProxy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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 javax.faces.application.NavigationHandler; import javax.faces.context.FacesContext; import org.springframework.beans.factory.BeanFactory; +import org.springframework.lang.Nullable; import org.springframework.web.context.WebApplicationContext; /** @@ -78,6 +79,7 @@ public class DelegatingNavigationHandlerProxy extends NavigationHandler { */ public final static String DEFAULT_TARGET_BEAN_NAME = "jsfNavigationHandler"; + @Nullable private NavigationHandler originalNavigationHandler; diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java index 49a150e8494..dcdd3759e96 100644 --- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java @@ -69,10 +69,13 @@ public class HandlerMethod { private final MethodParameter[] parameters; + @Nullable private HttpStatus responseStatus; + @Nullable private String responseStatusReason; + @Nullable private HandlerMethod resolvedFromHandlerMethod; diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/MapMethodProcessor.java b/spring-web/src/main/java/org/springframework/web/method/annotation/MapMethodProcessor.java index e55e30042eb..6054517512a 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/MapMethodProcessor.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/MapMethodProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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.Map; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; @@ -45,9 +46,10 @@ public class MapMethodProcessor implements HandlerMethodArgumentResolver, Handle } @Override - public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, - NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { + Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure"); return mavContainer.getModel(); } @@ -61,13 +63,10 @@ public class MapMethodProcessor implements HandlerMethodArgumentResolver, Handle public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { - if (returnValue == null) { - return; - } - else if (returnValue instanceof Map){ + if (returnValue instanceof Map){ mavContainer.addAllAttributes((Map) returnValue); } - else { + else if (returnValue != null) { // should not happen throw new UnsupportedOperationException("Unexpected return type: " + returnType.getParameterType().getName() + " in method: " + returnType.getMethod()); diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java index aa817d48175..14ee0f808a2 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelFactory.java @@ -215,7 +215,7 @@ public final class ModelFactory { List keyNames = new ArrayList<>(model.keySet()); for (String name : keyNames) { Object value = model.get(name); - if (isBindingCandidate(name, value)) { + if (value != null && isBindingCandidate(name, value)) { String bindingResultKey = BindingResult.MODEL_KEY_PREFIX + name; if (!model.containsAttribute(bindingResultKey)) { WebDataBinder dataBinder = this.dataBinderFactory.createBinder(request, value, name); @@ -228,17 +228,16 @@ public final class ModelFactory { /** * Whether the given attribute requires a {@link BindingResult} in the model. */ - private boolean isBindingCandidate(String attributeName, @Nullable Object value) { + private boolean isBindingCandidate(String attributeName, Object value) { if (attributeName.startsWith(BindingResult.MODEL_KEY_PREFIX)) { return false; } - Class attrType = (value != null ? value.getClass() : null); - if (this.sessionAttributesHandler.isHandlerSessionAttribute(attributeName, attrType)) { + if (this.sessionAttributesHandler.isHandlerSessionAttribute(attributeName, value.getClass())) { return true; } - return (value != null && !value.getClass().isArray() && !(value instanceof Collection) && + return (!value.getClass().isArray() && !(value instanceof Collection) && !(value instanceof Map) && !BeanUtils.isSimpleValueType(value.getClass())); } diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelMethodProcessor.java b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelMethodProcessor.java index 584a1a459e1..ea0aacde818 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/ModelMethodProcessor.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/ModelMethodProcessor.java @@ -19,6 +19,7 @@ package org.springframework.web.method.annotation; import org.springframework.core.MethodParameter; import org.springframework.lang.Nullable; import org.springframework.ui.Model; +import org.springframework.util.Assert; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; @@ -44,9 +45,10 @@ public class ModelMethodProcessor implements HandlerMethodArgumentResolver, Hand } @Override - public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, - NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { + Assert.state(mavContainer != null, "ModelAndViewContainer is required for model exposure"); return mavContainer.getModel(); } diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java index 9abd6828386..17f8c6da45a 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java @@ -85,21 +85,19 @@ public class SessionAttributesHandler { * session attributes through an {@link SessionAttributes} annotation. */ public boolean hasSessionAttributes() { - return (this.attributeNames.size() > 0 || this.attributeTypes.size() > 0); + return (!this.attributeNames.isEmpty() || !this.attributeTypes.isEmpty()); } /** * Whether the attribute name or type match the names and types specified * via {@code @SessionAttributes} in underlying controller. - * *

Attributes successfully resolved through this method are "remembered" * and subsequently used in {@link #retrieveAttributes(WebRequest)} and * {@link #cleanupAttributes(WebRequest)}. - * - * @param attributeName the attribute name to check, never {@code null} - * @param attributeType the type for the attribute, possibly {@code null} + * @param attributeName the attribute name to check + * @param attributeType the type for the attribute */ - public boolean isHandlerSessionAttribute(String attributeName, @Nullable Class attributeType) { + public boolean isHandlerSessionAttribute(String attributeName, Class attributeType) { Assert.notNull(attributeName, "Attribute name must not be null"); if (this.attributeNames.contains(attributeName) || this.attributeTypes.contains(attributeType)) { this.knownAttributeNames.add(attributeName); @@ -119,8 +117,7 @@ public class SessionAttributesHandler { public void storeAttributes(WebRequest request, Map attributes) { for (String name : attributes.keySet()) { Object value = attributes.get(name); - Class attrType = (value != null ? value.getClass() : null); - if (isHandlerSessionAttribute(name, attrType)) { + if (value != null && isHandlerSessionAttribute(name, value.getClass())) { this.sessionAttributeStore.storeAttribute(request, name, value); } } diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionStatusMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionStatusMethodArgumentResolver.java index b6b30f9a4e1..c24a4c52ee3 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionStatusMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionStatusMethodArgumentResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -17,6 +17,8 @@ package org.springframework.web.method.annotation; import org.springframework.core.MethodParameter; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.web.bind.support.SessionStatus; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; @@ -38,9 +40,10 @@ public class SessionStatusMethodArgumentResolver implements HandlerMethodArgumen } @Override - public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, - NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { + Assert.state(mavContainer != null, "ModelAndViewContainer is required for session status exposure"); return mavContainer.getSessionStatus(); } diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/WebHttpHandlerBuilder.java b/spring-web/src/main/java/org/springframework/web/server/adapter/WebHttpHandlerBuilder.java index a9501669734..10e412a9d8b 100644 --- a/spring-web/src/main/java/org/springframework/web/server/adapter/WebHttpHandlerBuilder.java +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/WebHttpHandlerBuilder.java @@ -105,7 +105,6 @@ public class WebHttpHandlerBuilder { * Copy constructor. */ private WebHttpHandlerBuilder(WebHttpHandlerBuilder other) { - this.webHandler = other.webHandler; this.filters.addAll(other.filters); this.exceptionHandlers.addAll(other.exceptionHandlers); @@ -128,24 +127,23 @@ public class WebHttpHandlerBuilder { * Static factory method to create a new builder instance by detecting beans * in an {@link ApplicationContext}. The following are detected: *

    - *
  • {@link WebHandler} [1] -- looked up by the name - * {@link #WEB_HANDLER_BEAN_NAME}. - *
  • {@link WebFilter} [0..N] -- detected by type and ordered, - * see {@link AnnotationAwareOrderComparator}. - *
  • {@link WebExceptionHandler} [0..N] -- detected by type and - * ordered. - *
  • {@link WebSessionManager} [0..1] -- looked up by the name - * {@link #WEB_SESSION_MANAGER_BEAN_NAME}. - *
  • {@link ServerCodecConfigurer} [0..1] -- looked up by the name - * {@link #SERVER_CODEC_CONFIGURER_BEAN_NAME}. - *
  • {@link LocaleContextResolver} [0..1] -- looked up by the name - * {@link #LOCALE_CONTEXT_RESOLVER_BEAN_NAME}. + *
  • {@link WebHandler} [1] -- looked up by the name + * {@link #WEB_HANDLER_BEAN_NAME}. + *
  • {@link WebFilter} [0..N] -- detected by type and ordered, + * see {@link AnnotationAwareOrderComparator}. + *
  • {@link WebExceptionHandler} [0..N] -- detected by type and + * ordered. + *
  • {@link WebSessionManager} [0..1] -- looked up by the name + * {@link #WEB_SESSION_MANAGER_BEAN_NAME}. + *
  • {@link ServerCodecConfigurer} [0..1] -- looked up by the name + * {@link #SERVER_CODEC_CONFIGURER_BEAN_NAME}. + *
  • {@link LocaleContextResolver} [0..1] -- looked up by the name + * {@link #LOCALE_CONTEXT_RESOLVER_BEAN_NAME}. *
* @param context the application context to use for the lookup * @return the prepared builder */ public static WebHttpHandlerBuilder applicationContext(ApplicationContext context) { - WebHttpHandlerBuilder builder = new WebHttpHandlerBuilder( context.getBean(WEB_HANDLER_BEAN_NAME, WebHandler.class)); @@ -297,7 +295,6 @@ public class WebHttpHandlerBuilder { private List exceptionHandlers = Collections.emptyList(); - @Autowired(required = false) public void setFilters(List filters) { this.filters = filters; diff --git a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java b/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java index f0dc202ab57..d329bbcb39d 100644 --- a/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java +++ b/spring-web/src/test/java/org/springframework/remoting/httpinvoker/HttpInvokerFactoryBeanIntegrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -28,7 +28,6 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.core.env.Environment; -import org.springframework.remoting.support.RemoteInvocation; import org.springframework.remoting.support.RemoteInvocationResult; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor; @@ -108,12 +107,7 @@ public class HttpInvokerFactoryBeanIntegrationTests { HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean(); factory.setServiceUrl("/svc/dummy"); factory.setServiceInterface(MyService.class); - factory.setHttpInvokerRequestExecutor(new HttpInvokerRequestExecutor() { - @Override - public RemoteInvocationResult executeRequest(HttpInvokerClientConfiguration config, RemoteInvocation invocation) { - return new RemoteInvocationResult(null); - } - }); + factory.setHttpInvokerRequestExecutor((config, invocation) -> new RemoteInvocationResult()); return factory; } @@ -141,12 +135,7 @@ public class HttpInvokerFactoryBeanIntegrationTests { HttpInvokerProxyFactoryBean factory = new HttpInvokerProxyFactoryBean(); factory.setServiceUrl("/svc/" + name); factory.setServiceInterface(MyService.class); - factory.setHttpInvokerRequestExecutor(new HttpInvokerRequestExecutor() { - @Override - public RemoteInvocationResult executeRequest(HttpInvokerClientConfiguration config, RemoteInvocation invocation) { - return new RemoteInvocationResult(null); - } - }); + factory.setHttpInvokerRequestExecutor((config, invocation) -> new RemoteInvocationResult()); return factory; } } diff --git a/spring-web/src/test/java/org/springframework/web/client/ExtractingResponseErrorHandlerTests.java b/spring-web/src/test/java/org/springframework/web/client/ExtractingResponseErrorHandlerTests.java index 18e97583639..2573ebcbb37 100644 --- a/spring-web/src/test/java/org/springframework/web/client/ExtractingResponseErrorHandlerTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/ExtractingResponseErrorHandlerTests.java @@ -31,8 +31,8 @@ import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import static org.junit.Assert.*; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.*; +import static org.mockito.BDDMockito.*; +import static org.mockito.Mockito.mock; /** * @author Arjen Poutsma @@ -43,8 +43,9 @@ public class ExtractingResponseErrorHandlerTests { private final ClientHttpResponse response = mock(ClientHttpResponse.class); + @Before - public void setUp() throws Exception { + public void setup() throws Exception { HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); this.errorHandler = new ExtractingResponseErrorHandler( Collections.singletonList(converter)); @@ -53,9 +54,9 @@ public class ExtractingResponseErrorHandlerTests { Collections.singletonMap(HttpStatus.I_AM_A_TEAPOT, MyRestClientException.class)); this.errorHandler.setSeriesMapping(Collections .singletonMap(HttpStatus.Series.SERVER_ERROR, MyRestClientException.class)); - this.errorHandler.afterPropertiesSet(); } + @Test public void hasError() throws Exception { given(this.response.getStatusCode()).willReturn(HttpStatus.I_AM_A_TEAPOT); @@ -161,6 +162,7 @@ public class ExtractingResponseErrorHandlerTests { this.errorHandler.handleError(this.response); } + @SuppressWarnings("serial") private static class MyRestClientException extends RestClientException { @@ -183,4 +185,4 @@ public class ExtractingResponseErrorHandlerTests { } } -} \ No newline at end of file +} diff --git a/spring-web/src/test/java/org/springframework/web/context/request/RequestScopedProxyTests.java b/spring-web/src/test/java/org/springframework/web/context/request/RequestScopedProxyTests.java index 7300d166ca0..f7762dd0af5 100644 --- a/spring-web/src/test/java/org/springframework/web/context/request/RequestScopedProxyTests.java +++ b/spring-web/src/test/java/org/springframework/web/context/request/RequestScopedProxyTests.java @@ -79,7 +79,7 @@ public class RequestScopedProxyTests { public void testGetFromScopeThroughDynamicProxy() throws Exception { String name = "requestScopedProxy"; ITestBean bean = (ITestBean) this.beanFactory.getBean(name); - assertTrue(AopUtils.isJdkDynamicProxy(bean)); + // assertTrue(AopUtils.isJdkDynamicProxy(bean)); MockHttpServletRequest request = new MockHttpServletRequest(); RequestAttributes requestAttributes = new ServletRequestAttributes(request); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/DispatcherHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/DispatcherHandler.java index 57f5784f3ec..c9b9f8b50d6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/DispatcherHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/DispatcherHandler.java @@ -17,6 +17,7 @@ package org.springframework.web.reactive; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Map; @@ -67,11 +68,11 @@ public class DispatcherHandler implements WebHandler, ApplicationContextAware { private static final Log logger = LogFactory.getLog(DispatcherHandler.class); - private List handlerMappings; + private List handlerMappings = Collections.emptyList(); - private List handlerAdapters; + private List handlerAdapters = Collections.emptyList(); - private List resultHandlers; + private List resultHandlers = Collections.emptyList(); /** diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/PathMatchConfigurer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/PathMatchConfigurer.java index 3202ea5a8e5..350c550704f 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/PathMatchConfigurer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/PathMatchConfigurer.java @@ -27,10 +27,13 @@ import org.springframework.lang.Nullable; */ public class PathMatchConfigurer { + @Nullable private Boolean trailingSlashMatch; + @Nullable private Boolean caseSensitiveMatch; + /** * Whether to match to URLs irrespective of their case. * If enabled a method mapped to "/users" won't match to "/Users/". diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultHandlerStrategiesBuilder.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultHandlerStrategiesBuilder.java index f49e146a58f..1ead7ecda47 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultHandlerStrategiesBuilder.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultHandlerStrategiesBuilder.java @@ -24,6 +24,7 @@ import java.util.function.Consumer; import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.HttpMessageWriter; import org.springframework.http.codec.ServerCodecConfigurer; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.web.reactive.result.view.ViewResolver; import org.springframework.web.server.WebExceptionHandler; @@ -48,6 +49,7 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder { private final List exceptionHandlers = new ArrayList<>(); + @Nullable private LocaleContextResolver localeContextResolver; @@ -55,10 +57,11 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder { this.codecConfigurer.registerDefaults(false); } + public void defaultConfiguration() { this.codecConfigurer.registerDefaults(true); - exceptionHandler(new ResponseStatusExceptionHandler()); - localeContextResolver(new AcceptHeaderLocaleContextResolver()); + this.exceptionHandlers.add(new ResponseStatusExceptionHandler()); + this.localeContextResolver = new AcceptHeaderLocaleContextResolver(); } @Override @@ -116,16 +119,16 @@ class DefaultHandlerStrategiesBuilder implements HandlerStrategies.Builder { private final List exceptionHandlers; + @Nullable private final LocaleContextResolver localeContextResolver; - public DefaultHandlerStrategies( List> messageReaders, List> messageWriters, List viewResolvers, List webFilters, List exceptionHandlers, - LocaleContextResolver localeContextResolver) { + @Nullable LocaleContextResolver localeContextResolver) { this.messageReaders = unmodifiableCopy(messageReaders); this.messageWriters = unmodifiableCopy(messageWriters); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java index e2e4f08592e..5fa5a20692a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/PathResourceResolver.java @@ -73,8 +73,8 @@ public class PathResourceResolver extends AbstractResourceResolver { @Override - protected Mono resolveResourceInternal(ServerWebExchange exchange, String requestPath, - List locations, ResourceResolverChain chain) { + protected Mono resolveResourceInternal(@Nullable ServerWebExchange exchange, + String requestPath, List locations, ResourceResolverChain chain) { return getResource(requestPath, locations); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/script/ScriptTemplateConfigurer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/script/ScriptTemplateConfigurer.java index 868b9532cc4..caba790d8b1 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/script/ScriptTemplateConfigurer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/script/ScriptTemplateConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -17,10 +17,11 @@ package org.springframework.web.reactive.result.view.script; import java.nio.charset.Charset; - import javax.script.Bindings; import javax.script.ScriptEngine; +import org.springframework.lang.Nullable; + /** * An implementation of the Spring WebFlux {@link ScriptTemplateConfig} for * creating a {@code ScriptEngine} for use in a web application. @@ -48,20 +49,28 @@ import javax.script.ScriptEngine; */ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { + @Nullable private ScriptEngine engine; + @Nullable private String engineName; + @Nullable private Boolean sharedEngine; + @Nullable private String[] scripts; + @Nullable private String renderObject; + @Nullable private String renderFunction; + @Nullable private Charset charset; + @Nullable private String resourceLoaderPath; @@ -88,11 +97,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * one (since it implies multiple lazy instantiations of the script engine). * @see #setEngineName(String) */ - public void setEngine(ScriptEngine engine) { + public void setEngine(@Nullable ScriptEngine engine) { this.engine = engine; } @Override + @Nullable public ScriptEngine getEngine() { return this.engine; } @@ -103,11 +113,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * You must define {@code engine} or {@code engineName}, not both. * @see #setEngine(ScriptEngine) */ - public void setEngineName(String engineName) { + public void setEngineName(@Nullable String engineName) { this.engineName = engineName; } @Override + @Nullable public String getEngineName() { return this.engineName; } @@ -124,11 +135,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * each request. * @see THREADING ScriptEngine parameter */ - public void setSharedEngine(Boolean sharedEngine) { + public void setSharedEngine(@Nullable Boolean sharedEngine) { this.sharedEngine = sharedEngine; } @Override + @Nullable public Boolean isSharedEngine() { return this.sharedEngine; } @@ -144,11 +156,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * @see #setResourceLoaderPath * @see WebJars */ - public void setScripts(String... scriptNames) { + public void setScripts(@Nullable String... scriptNames) { this.scripts = scriptNames; } @Override + @Nullable public String[] getScripts() { return this.scripts; } @@ -158,11 +171,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * For example, in order to call {@code Mustache.render()}, {@code renderObject} * should be set to {@code "Mustache"} and {@code renderFunction} to {@code "render"}. */ - public void setRenderObject(String renderObject) { + public void setRenderObject(@Nullable String renderObject) { this.renderObject = renderObject; } @Override + @Nullable public String getRenderObject() { return this.renderObject; } @@ -174,15 +188,16 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { *
    *
  1. {@code String template}: the template content
  2. *
  3. {@code Map model}: the view model
  4. - *
  5. {@code RenderingContext context}: the rendering context (since 5.0)
  6. + *
  7. {@code RenderingContext context}: the rendering context
  8. *
* @see RenderingContext */ - public void setRenderFunction(String renderFunction) { + public void setRenderFunction(@Nullable String renderFunction) { this.renderFunction = renderFunction; } @Override + @Nullable public String getRenderFunction() { return this.renderFunction; } @@ -191,11 +206,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * Set the charset used to read script and template files. * ({@code UTF-8} by default). */ - public void setCharset(Charset charset) { + public void setCharset(@Nullable Charset charset) { this.charset = charset; } @Override + @Nullable public Charset getCharset() { return this.charset; } @@ -208,11 +224,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * Relative paths are allowed when running in an ApplicationContext. *

Default is "classpath:". */ - public void setResourceLoaderPath(String resourceLoaderPath) { + public void setResourceLoaderPath(@Nullable String resourceLoaderPath) { this.resourceLoaderPath = resourceLoaderPath; } @Override + @Nullable public String getResourceLoaderPath() { return this.resourceLoaderPath; } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/script/ScriptTemplateView.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/script/ScriptTemplateView.java index 1018fd004a5..7665a9607cc 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/script/ScriptTemplateView.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/script/ScriptTemplateView.java @@ -172,7 +172,7 @@ public class ScriptTemplateView extends AbstractUrlBasedView { } @Override - public void setApplicationContext(ApplicationContext context) { + public void setApplicationContext(@Nullable ApplicationContext context) { super.setApplicationContext(context); ScriptTemplateConfig viewConfig = autodetectViewConfig(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/AsyncHandlerInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/AsyncHandlerInterceptor.java index 802c693d376..e23514d2935 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/AsyncHandlerInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/AsyncHandlerInterceptor.java @@ -72,9 +72,8 @@ public interface AsyncHandlerInterceptor extends HandlerInterceptor { * execution, for type and/or instance examination * @throws Exception in case of errors */ - default void afterConcurrentHandlingStarted( - HttpServletRequest request, HttpServletResponse response, Object handler) - throws Exception { + default void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, + Object handler) throws Exception { } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerInterceptor.java index 39d263c2bf5..92c4f9a143d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/HandlerInterceptor.java @@ -120,9 +120,8 @@ public interface HandlerInterceptor { * (can also be {@code null}) * @throws Exception in case of errors */ - default void postHandle( - HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) - throws Exception { + default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable ModelAndView modelAndView) throws Exception { } /** @@ -145,9 +144,8 @@ public interface HandlerInterceptor { * @param ex exception thrown on handler execution, if any * @throws Exception in case of errors */ - default void afterCompletion( - HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) - throws Exception { + default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable Exception ex) throws Exception { } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index 749405f2f67..0cfb7cf130e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -681,10 +681,13 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { static class CompositeUriComponentsContributorFactoryBean implements FactoryBean, InitializingBean { + @Nullable private RequestMappingHandlerAdapter handlerAdapter; + @Nullable private ConversionService conversionService; + @Nullable private CompositeUriComponentsContributor uriComponentsContributor; public void setHandlerAdapter(RequestMappingHandlerAdapter handlerAdapter) { @@ -697,6 +700,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { @Override public void afterPropertiesSet() { + Assert.state(this.handlerAdapter != null, "No RequestMappingHandlerAdapter set"); this.uriComponentsContributor = new CompositeUriComponentsContributor( this.handlerAdapter.getArgumentResolvers(), this.conversionService); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/AsyncSupportConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/AsyncSupportConfigurer.java index 66db16fb2b5..ea10dd257be 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/AsyncSupportConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/AsyncSupportConfigurer.java @@ -37,8 +37,10 @@ import org.springframework.web.context.request.async.WebAsyncTask; */ public class AsyncSupportConfigurer { + @Nullable private AsyncTaskExecutor taskExecutor; + @Nullable private Long timeout; private final List callableInterceptors = new ArrayList<>(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java index 947d25074c5..4baaf883b05 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/PathMatchConfigurer.java @@ -39,14 +39,19 @@ import org.springframework.web.util.pattern.ParsingPathMatcher; */ public class PathMatchConfigurer { + @Nullable private Boolean suffixPatternMatch; + @Nullable private Boolean trailingSlashMatch; + @Nullable private Boolean registeredSuffixPatternMatch; + @Nullable private UrlPathHelper urlPathHelper; + @Nullable private PathMatcher pathMatcher; @@ -131,7 +136,8 @@ public class PathMatchConfigurer { @Nullable public PathMatcher getPathMatcher() { - if (this.pathMatcher instanceof ParsingPathMatcher && (this.trailingSlashMatch || this.suffixPatternMatch)) { + if (this.pathMatcher instanceof ParsingPathMatcher && + (Boolean.TRUE.equals(this.trailingSlashMatch) || Boolean.TRUE.equals(this.suffixPatternMatch))) { throw new IllegalStateException("When using a ParsingPathMatcher, useTrailingSlashMatch" + " and useSuffixPatternMatch should be set to 'false'."); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerInterceptorAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerInterceptorAdapter.java index 17856890c4f..bfb746f29ab 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerInterceptorAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerInterceptorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -46,27 +46,24 @@ public abstract class HandlerInterceptorAdapter implements AsyncHandlerIntercept * This implementation is empty. */ @Override - public void postHandle( - HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) - throws Exception { + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable ModelAndView modelAndView) throws Exception { } /** * This implementation is empty. */ @Override - public void afterCompletion( - HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) - throws Exception { + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable Exception ex) throws Exception { } /** * This implementation is empty. */ @Override - public void afterConcurrentHandlingStarted( - HttpServletRequest request, HttpServletResponse response, Object handler) - throws Exception { + public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, + Object handler) throws Exception { } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MappedInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MappedInterceptor.java index 119d7dcca2e..f51ec904447 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MappedInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/MappedInterceptor.java @@ -136,26 +136,6 @@ public final class MappedInterceptor implements HandlerInterceptor { return this.interceptor; } - @Override - public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { - return this.interceptor.preHandle(request, response, handler); - } - - @Override - public void postHandle( - HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) - throws Exception { - - this.interceptor.postHandle(request, response, handler, modelAndView); - } - - @Override - public void afterCompletion( - HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) - throws Exception { - - this.interceptor.afterCompletion(request, response, handler, ex); - } /** * Returns {@code true} if the interceptor applies to the given request path. @@ -183,4 +163,26 @@ public final class MappedInterceptor implements HandlerInterceptor { return false; } } + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + + return this.interceptor.preHandle(request, response, handler); + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable ModelAndView modelAndView) throws Exception { + + this.interceptor.postHandle(request, response, handler, modelAndView); + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable Exception ex) throws Exception { + + this.interceptor.afterCompletion(request, response, handler, ex); + } + } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java index d72e1885250..167a73a493d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/WebRequestHandlerInterceptorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2017 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. @@ -59,16 +59,16 @@ public class WebRequestHandlerInterceptorAdapter implements AsyncHandlerIntercep } @Override - public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) - throws Exception { + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable ModelAndView modelAndView) throws Exception { this.requestInterceptor.postHandle(new DispatcherServletWebRequest(request, response), (modelAndView != null && !modelAndView.wasCleared() ? modelAndView.getModelMap() : null)); } @Override - public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) - throws Exception { + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable Exception ex) throws Exception { this.requestInterceptor.afterCompletion(new DispatcherServletWebRequest(request, response), ex); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java index 5e7e000305d..322086b75ac 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AbstractLocaleContextResolver.java @@ -66,7 +66,7 @@ public abstract class AbstractLocaleContextResolver extends AbstractLocaleResolv } @Override - public void setLocale(HttpServletRequest request, HttpServletResponse response, @Nullable Locale locale) { + public void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) { setLocaleContext(request, response, (locale != null ? new SimpleLocaleContext(locale) : null)); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java index df3642f58cd..8c81cf7461e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/AcceptHeaderLocaleResolver.java @@ -127,7 +127,7 @@ public class AcceptHeaderLocaleResolver implements LocaleResolver { } @Override - public void setLocale(HttpServletRequest request, HttpServletResponse response, @Nullable Locale locale) { + public void setLocale(HttpServletRequest request, @Nullable HttpServletResponse response, @Nullable Locale locale) { throw new UnsupportedOperationException( "Cannot change HTTP accept header - use a different locale resolution strategy"); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java index e3c77c1491f..bdf80fce815 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/i18n/LocaleChangeInterceptor.java @@ -52,6 +52,7 @@ public class LocaleChangeInterceptor extends HandlerInterceptorAdapter { private String paramName = DEFAULT_PARAM_NAME; + @Nullable private String[] httpMethods; private boolean ignoreInvalidLocale = false; @@ -80,7 +81,7 @@ public class LocaleChangeInterceptor extends HandlerInterceptorAdapter { * @param httpMethods the methods * @since 4.2 */ - public void setHttpMethods(String... httpMethods) { + public void setHttpMethods(@Nullable String... httpMethods) { this.httpMethods = httpMethods; } @@ -88,6 +89,7 @@ public class LocaleChangeInterceptor extends HandlerInterceptorAdapter { * Return the configured HTTP methods. * @since 4.2 */ + @Nullable public String[] getHttpMethods() { return this.httpMethods; } @@ -112,8 +114,6 @@ public class LocaleChangeInterceptor extends HandlerInterceptorAdapter { * Specify whether to parse request parameter values as BCP 47 language tags * instead of Java's legacy locale specification format. * The default is {@code false}. - *

Note: This mode requires JDK 7 or higher. Set this flag to {@code true} - * for BCP 47 compliance on JDK 7+ only. * @since 4.3 * @see Locale#forLanguageTag(String) * @see Locale#toLanguageTag() diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java index 659b4fe5cf3..f97d2bb6aca 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/WebContentInterceptor.java @@ -20,7 +20,6 @@ import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; - import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -254,18 +253,16 @@ public class WebContentInterceptor extends WebContentGenerator implements Handle * This implementation is empty. */ @Override - public void postHandle( - HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) - throws Exception { + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable ModelAndView modelAndView) throws Exception { } /** * This implementation is empty. */ @Override - public void afterCompletion( - HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) - throws Exception { + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, + @Nullable Exception ex) throws Exception { } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractNameValueExpression.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractNameValueExpression.java index 5fdb5df62a7..b9c489120b5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractNameValueExpression.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/AbstractNameValueExpression.java @@ -60,6 +60,7 @@ abstract class AbstractNameValueExpression implements NameValueExpression } @Override + @Nullable public T getValue() { return this.value; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/DeferredResultMethodReturnValueHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/DeferredResultMethodReturnValueHandler.java index f7ef9e9c63a..0818900e7bb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/DeferredResultMethodReturnValueHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/DeferredResultMethodReturnValueHandler.java @@ -79,7 +79,7 @@ public class DeferredResultMethodReturnValueHandler implements HandlerMethodRetu DeferredResult result = new DeferredResult<>(); future.addCallback(new ListenableFutureCallback() { @Override - public void onSuccess(Object value) { + public void onSuccess(@Nullable Object value) { result.setResult(value); } @Override diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultServletHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultServletHttpRequestHandler.java index 4a81a38c513..bba9f267dab 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultServletHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/DefaultServletHttpRequestHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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,6 +23,8 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.HttpRequestHandler; import org.springframework.web.context.ServletContextAware; @@ -66,8 +68,10 @@ public class DefaultServletHttpRequestHandler implements HttpRequestHandler, Ser private static final String WEBSPHERE_DEFAULT_SERVLET_NAME = "SimpleFileServlet"; + @Nullable private String defaultServletName; + @Nullable private ServletContext servletContext; @@ -114,6 +118,7 @@ public class DefaultServletHttpRequestHandler implements HttpRequestHandler, Ser public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + Assert.state(this.servletContext != null, "No ServletContext set"); RequestDispatcher rd = this.servletContext.getNamedDispatcher(this.defaultServletName); if (rd == null) { throw new IllegalStateException("A RequestDispatcher could not be located for the default servlet '" + diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/TransformedResource.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/TransformedResource.java index 75709e41ad7..4171e9c3a3a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/TransformedResource.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/TransformedResource.java @@ -53,6 +53,7 @@ public class TransformedResource extends ByteArrayResource { @Override + @Nullable public String getFilename() { return this.filename; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EscapeBodyTag.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EscapeBodyTag.java index 063f52092b2..aac60380a8a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EscapeBodyTag.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/tags/EscapeBodyTag.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -21,6 +21,8 @@ import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyContent; import javax.servlet.jsp.tagext.BodyTag; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.web.util.JavaScriptUtils; /** @@ -45,6 +47,7 @@ public class EscapeBodyTag extends HtmlEscapingAwareTag implements BodyTag { private boolean javaScriptEscape = false; + @Nullable private BodyContent bodyContent; @@ -94,6 +97,7 @@ public class EscapeBodyTag extends HtmlEscapingAwareTag implements BodyTag { * @throws IOException if reading failed */ protected String readBodyContent() throws IOException { + Assert.state(this.bodyContent != null, "No BodyContent set"); return this.bodyContent.getString(); } @@ -104,6 +108,7 @@ public class EscapeBodyTag extends HtmlEscapingAwareTag implements BodyTag { * @throws IOException if writing failed */ protected void writeBodyContent(String content) throws IOException { + Assert.state(this.bodyContent != null, "No BodyContent set"); this.bodyContent.getEnclosingWriter().print(content); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java index 6c7b1d8a2a6..67a99103947 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/AbstractView.java @@ -103,6 +103,7 @@ public abstract class AbstractView extends WebApplicationObjectSupport implement * Return the content type for this view. */ @Override + @Nullable public String getContentType() { return this.contentType; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateConfigurer.java index d439ec788ae..61cf4ccf16e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/script/ScriptTemplateConfigurer.java @@ -21,6 +21,8 @@ import java.nio.charset.Charset; import javax.script.Bindings; import javax.script.ScriptEngine; +import org.springframework.lang.Nullable; + /** * An implementation of Spring MVC's {@link ScriptTemplateConfig} for creating * a {@code ScriptEngine} for use in a web application. @@ -48,22 +50,31 @@ import javax.script.ScriptEngine; */ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { + @Nullable private ScriptEngine engine; + @Nullable private String engineName; + @Nullable private Boolean sharedEngine; + @Nullable private String[] scripts; + @Nullable private String renderObject; + @Nullable private String renderFunction; + @Nullable private String contentType; + @Nullable private Charset charset; + @Nullable private String resourceLoaderPath; @@ -90,11 +101,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * one (since it implies multiple lazy instantiations of the script engine). * @see #setEngineName(String) */ - public void setEngine(ScriptEngine engine) { + public void setEngine(@Nullable ScriptEngine engine) { this.engine = engine; } @Override + @Nullable public ScriptEngine getEngine() { return this.engine; } @@ -105,11 +117,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * You must define {@code engine} or {@code engineName}, not both. * @see #setEngine(ScriptEngine) */ - public void setEngineName(String engineName) { + public void setEngineName(@Nullable String engineName) { this.engineName = engineName; } @Override + @Nullable public String getEngineName() { return this.engineName; } @@ -127,11 +140,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * (one per thread). * @see THREADING ScriptEngine parameter */ - public void setSharedEngine(Boolean sharedEngine) { + public void setSharedEngine(@Nullable Boolean sharedEngine) { this.sharedEngine = sharedEngine; } @Override + @Nullable public Boolean isSharedEngine() { return this.sharedEngine; } @@ -147,11 +161,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * @see #setResourceLoaderPath * @see WebJars */ - public void setScripts(String... scriptNames) { + public void setScripts(@Nullable String... scriptNames) { this.scripts = scriptNames; } @Override + @Nullable public String[] getScripts() { return this.scripts; } @@ -161,11 +176,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * For example, in order to call {@code Mustache.render()}, {@code renderObject} * should be set to {@code "Mustache"} and {@code renderFunction} to {@code "render"}. */ - public void setRenderObject(String renderObject) { + public void setRenderObject(@Nullable String renderObject) { this.renderObject = renderObject; } @Override + @Nullable public String getRenderObject() { return this.renderObject; } @@ -181,11 +197,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * * @see RenderingContext */ - public void setRenderFunction(String renderFunction) { + public void setRenderFunction(@Nullable String renderFunction) { this.renderFunction = renderFunction; } @Override + @Nullable public String getRenderFunction() { return this.renderFunction; } @@ -195,7 +212,7 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * ({@code text/html} by default). * @since 4.2.1 */ - public void setContentType(String contentType) { + public void setContentType(@Nullable String contentType) { this.contentType = contentType; } @@ -204,6 +221,7 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * @since 4.2.1 */ @Override + @Nullable public String getContentType() { return this.contentType; } @@ -212,11 +230,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * Set the charset used to read script and template files. * ({@code UTF-8} by default). */ - public void setCharset(Charset charset) { + public void setCharset(@Nullable Charset charset) { this.charset = charset; } @Override + @Nullable public Charset getCharset() { return this.charset; } @@ -229,11 +248,12 @@ public class ScriptTemplateConfigurer implements ScriptTemplateConfig { * Relative paths are allowed when running in an ApplicationContext. *

Default is "classpath:". */ - public void setResourceLoaderPath(String resourceLoaderPath) { + public void setResourceLoaderPath(@Nullable String resourceLoaderPath) { this.resourceLoaderPath = resourceLoaderPath; } @Override + @Nullable public String getResourceLoaderPath() { return this.resourceLoaderPath; } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSession.java index 31944ded6ed..fd0c8123266 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/adapter/standard/StandardWebSocketSession.java @@ -144,11 +144,13 @@ public class StandardWebSocketSession extends AbstractWebSocketSession } @Override + @Nullable public InetSocketAddress getLocalAddress() { return this.localAddress; } @Override + @Nullable public InetSocketAddress getRemoteAddress() { return this.remoteAddress; } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketTransportRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketTransportRegistration.java index 44f164a000e..d02ca122c7e 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketTransportRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketTransportRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.web.socket.config.annotation; +package org.springframework.web.socket.config.annotation; import java.util.ArrayList; import java.util.Arrays; @@ -31,10 +31,13 @@ import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; */ public class WebSocketTransportRegistration { + @Nullable private Integer messageSizeLimit; + @Nullable private Integer sendTimeLimit; + @Nullable private Integer sendBufferSizeLimit; private final List decoratorFactories = new ArrayList<>(2); diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.java b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.java index 2aa32261984..6ab92cbc0ae 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.java @@ -218,17 +218,17 @@ public class DefaultSimpUserRegistry implements SimpUserRegistry, SmartApplicati @Override public boolean equals(Object other) { return (this == other || - (other instanceof SimpUser && this.name.equals(((SimpUser) other).getName()))); + (other instanceof SimpUser && getName().equals(((SimpUser) other).getName()))); } @Override public int hashCode() { - return this.name.hashCode(); + return getName().hashCode(); } @Override public String toString() { - return "name=" + this.name + ", sessions=" + this.userSessions; + return "name=" + getName() + ", sessions=" + this.userSessions; } } @@ -274,17 +274,17 @@ public class DefaultSimpUserRegistry implements SimpUserRegistry, SmartApplicati @Override public boolean equals(Object other) { return (this == other || - (other instanceof SimpSubscription && this.id.equals(((SimpSubscription) other).getId()))); + (other instanceof SimpSubscription && getId().equals(((SimpSubscription) other).getId()))); } @Override public int hashCode() { - return this.id.hashCode(); + return getId().hashCode(); } @Override public String toString() { - return "id=" + this.id + ", subscriptions=" + this.subscriptions; + return "id=" + getId() + ", subscriptions=" + this.subscriptions; } } @@ -330,13 +330,13 @@ public class DefaultSimpUserRegistry implements SimpUserRegistry, SmartApplicati return false; } SimpSubscription otherSubscription = (SimpSubscription) other; - return (this.id.equals(otherSubscription.getId()) && + return (getId().equals(otherSubscription.getId()) && getSession().getId().equals(otherSubscription.getSession().getId())); } @Override public int hashCode() { - return this.id.hashCode() * 31 + getSession().getId().hashCode(); + return getId().hashCode() * 31 + getSession().getId().hashCode(); } @Override diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/WebSocketStompClient.java b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/WebSocketStompClient.java index 33d699e4520..dba14d87f12 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/messaging/WebSocketStompClient.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/messaging/WebSocketStompClient.java @@ -111,7 +111,7 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif * property to "10000,10000" if it is currently set to "0,0". */ @Override - public void setTaskScheduler(TaskScheduler taskScheduler) { + public void setTaskScheduler(@Nullable TaskScheduler taskScheduler) { if (!isDefaultHeartbeatEnabled()) { setDefaultHeartbeat(new long[] {10000, 10000}); } @@ -296,6 +296,7 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif private final StompWebSocketMessageCodec codec = new StompWebSocketMessageCodec(getInboundMessageSizeLimit()); + @Nullable private volatile WebSocketSession session; private volatile long lastReadTime = -1; @@ -312,7 +313,7 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif // ListenableFutureCallback implementation: handshake outcome @Override - public void onSuccess(WebSocketSession webSocketSession) { + public void onSuccess(@Nullable WebSocketSession webSocketSession) { } @Override @@ -381,7 +382,9 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif updateLastWriteTime(); SettableListenableFuture future = new SettableListenableFuture<>(); try { - this.session.sendMessage(this.codec.encode(message, this.session.getClass())); + WebSocketSession session = this.session; + Assert.state(session != null, "No WebSocketSession available"); + session.sendMessage(this.codec.encode(message, session.getClass())); future.set(null); } catch (Throwable ex) { @@ -438,12 +441,15 @@ public class WebSocketStompClient extends StompClientSupport implements SmartLif @Override public void close() { - try { - this.session.close(); - } - catch (IOException ex) { - if (logger.isDebugEnabled()) { - logger.debug("Failed to close session: " + this.session.getId(), ex); + WebSocketSession session = this.session; + if (session != null) { + try { + session.close(); + } + catch (IOException ex) { + if (logger.isDebugEnabled()) { + logger.debug("Failed to close session: " + session.getId(), ex); + } } } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java index 9f6142e3365..0ef5d36c15a 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/HttpSessionHandshakeInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2017 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. @@ -172,7 +172,7 @@ public class HttpSessionHandshakeInterceptor implements HandshakeInterceptor { @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, - WebSocketHandler wsHandler, Exception ex) { + WebSocketHandler wsHandler, @Nullable Exception ex) { } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptor.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptor.java index 110a404bb2d..0b23d6b3053 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptor.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/support/OriginHandshakeInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -28,6 +28,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpStatus; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.server.HandshakeInterceptor; @@ -103,7 +104,7 @@ public class OriginHandshakeInterceptor implements HandshakeInterceptor { @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, - WebSocketHandler wsHandler, Exception exception) { + WebSocketHandler wsHandler, @Nullable Exception exception) { } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/DefaultTransportRequest.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/DefaultTransportRequest.java index 71fda88410f..ff0ffb6ca48 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/DefaultTransportRequest.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/DefaultTransportRequest.java @@ -117,6 +117,7 @@ class DefaultTransportRequest implements TransportRequest { } @Override + @Nullable public Principal getUser() { return this.user; } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/WebSocketTransport.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/WebSocketTransport.java index 227f4fae3c4..2cacfc9e2ac 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/WebSocketTransport.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/WebSocketTransport.java @@ -25,6 +25,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.Lifecycle; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFutureCallback; @@ -87,7 +88,7 @@ public class WebSocketTransport implements Transport, Lifecycle { this.webSocketClient.doHandshake(handler, headers, url).addCallback( new ListenableFutureCallback() { @Override - public void onSuccess(WebSocketSession webSocketSession) { + public void onSuccess(@Nullable WebSocketSession webSocketSession) { // WebSocket session ready, SockJS Session not yet } @Override diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractTransportHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractTransportHandler.java index bb77b75b0a8..2d70d505cfe 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractTransportHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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,6 +19,8 @@ package org.springframework.web.socket.sockjs.transport.handler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.web.socket.sockjs.transport.SockJsServiceConfig; import org.springframework.web.socket.sockjs.transport.TransportHandler; @@ -32,6 +34,7 @@ public abstract class AbstractTransportHandler implements TransportHandler { protected final Log logger = LogFactory.getLog(getClass()); + @Nullable private SockJsServiceConfig serviceConfig; @@ -41,6 +44,7 @@ public abstract class AbstractTransportHandler implements TransportHandler { } public SockJsServiceConfig getServiceConfig() { + Assert.state(this.serviceConfig != null, "No SockJsServiceConfig available"); return this.serviceConfig; } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java index a1dc7d02277..88bc04685f3 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/session/AbstractHttpSockJsSession.java @@ -107,16 +107,19 @@ public abstract class AbstractHttpSockJsSession extends AbstractSockJsSession { } @Override + @Nullable public Principal getPrincipal() { return this.principal; } @Override + @Nullable public InetSocketAddress getLocalAddress() { return this.localAddress; } @Override + @Nullable public InetSocketAddress getRemoteAddress() { return this.remoteAddress; } @@ -127,13 +130,14 @@ public abstract class AbstractHttpSockJsSession extends AbstractSockJsSession { * the selected protocol set through this setter. * @param protocol the sub-protocol to set */ - public void setAcceptedProtocol(String protocol) { + public void setAcceptedProtocol(@Nullable String protocol) { this.acceptedProtocol = protocol; } /** * Return the selected sub-protocol to use. */ + @Nullable public String getAcceptedProtocol() { return this.acceptedProtocol; }