Consistent use of @Nullable across the codebase (even for internals)

Beyond just formally declaring the current behavior, this revision actually enforces non-null behavior in selected signatures now, not tolerating null values anymore when not explicitly documented. It also changes some utility methods with historic null-in/null-out tolerance towards enforced non-null return values, making them a proper citizen in non-null assignments.

Some issues are left as to-do: in particular a thorough revision of spring-test, and a few tests with unclear failures (ignored as "TODO: NULLABLE") to be sorted out in a follow-up commit.

Issue: SPR-15540
This commit is contained in:
Juergen Hoeller
2017-06-07 14:17:48 +02:00
parent ffc3f6d87d
commit f813712f5b
1493 changed files with 10670 additions and 9172 deletions

View File

@@ -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.
@@ -57,7 +57,7 @@ public interface Cache {
* @see #get(Object, Class)
*/
@Nullable
ValueWrapper get(@Nullable Object key);
ValueWrapper get(Object key);
/**
* Return the value to which this cache maps the specified key,
@@ -78,7 +78,7 @@ public interface Cache {
* @see #get(Object)
*/
@Nullable
<T> T get(@Nullable Object key, Class<T> type);
<T> T get(Object key, @Nullable Class<T> type);
/**
* Return the value to which this cache maps the specified key, obtaining
@@ -96,7 +96,7 @@ public interface Cache {
* @since 4.3
*/
@Nullable
<T> T get(@Nullable Object key, Callable<T> valueLoader);
<T> T get(Object key, Callable<T> valueLoader);
/**
* Associate the specified value with the specified key in this cache.
@@ -105,7 +105,7 @@ public interface Cache {
* @param key the key with which the specified value is to be associated
* @param value the value to be associated with the specified key
*/
void put(@Nullable Object key, @Nullable Object value);
void put(Object key, @Nullable Object value);
/**
* Atomically associate the specified value with the specified key in this cache
@@ -134,13 +134,13 @@ public interface Cache {
* @since 4.1
*/
@Nullable
ValueWrapper putIfAbsent(@Nullable Object key, @Nullable Object value);
ValueWrapper putIfAbsent(Object key, @Nullable Object value);
/**
* Evict the mapping for this key from this cache if it is present.
* @param key the key whose mapping is to be removed from the cache
*/
void evict(@Nullable Object key);
void evict(Object key);
/**
* Remove all mappings from the cache.

View File

@@ -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.
@@ -27,7 +27,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
/**
@@ -81,7 +80,7 @@ public abstract class AbstractCachingConfiguration implements ImportAware {
/**
* Extract the configuration from the nominated {@link CachingConfigurer}.
*/
protected void useCachingConfigurer(@Nullable CachingConfigurer config) {
protected void useCachingConfigurer(CachingConfigurer config) {
this.cacheManager = config.cacheManager();
this.cacheResolver = config.cacheResolver();
this.keyGenerator = config.keyGenerator();

View File

@@ -28,6 +28,7 @@ import org.springframework.cache.interceptor.CacheOperation;
import org.springframework.cache.interceptor.CachePutOperation;
import org.springframework.cache.interceptor.CacheableOperation;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -58,6 +59,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
return parseCacheAnnotations(defaultConfig, method);
}
@Nullable
protected Collection<CacheOperation> parseCacheAnnotations(DefaultCacheConfig cachingConfig, AnnotatedElement ae) {
Collection<CacheOperation> ops = parseCacheAnnotations(cachingConfig, ae, false);
if (ops != null && ops.size() > 1 && ae.getAnnotations().length > 0) {
@@ -70,6 +72,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
return ops;
}
@Nullable
private Collection<CacheOperation> parseCacheAnnotations(
DefaultCacheConfig cachingConfig, AnnotatedElement ae, boolean localOnly) {
@@ -78,7 +81,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
Collection<Cacheable> cacheables = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, Cacheable.class) :
AnnotatedElementUtils.findAllMergedAnnotations(ae, Cacheable.class));
if (!cacheables.isEmpty()) {
ops = lazyInit(ops);
ops = lazyInit(null);
for (Cacheable cacheable : cacheables) {
ops.add(parseCacheableAnnotation(ae, cachingConfig, cacheable));
}
@@ -114,7 +117,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
return ops;
}
private <T extends Annotation> Collection<CacheOperation> lazyInit(Collection<CacheOperation> ops) {
private <T extends Annotation> Collection<CacheOperation> lazyInit(@Nullable Collection<CacheOperation> ops) {
return (ops != null ? ops : new ArrayList<>(1));
}
@@ -177,12 +180,13 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
return op;
}
@Nullable
Collection<CacheOperation> parseCachingAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, Caching caching) {
Collection<CacheOperation> ops = null;
Cacheable[] cacheables = caching.cacheable();
if (!ObjectUtils.isEmpty(cacheables)) {
ops = lazyInit(ops);
ops = lazyInit(null);
for (Cacheable cacheable : cacheables) {
ops.add(parseCacheableAnnotation(ae, defaultConfig, cacheable));
}
@@ -271,7 +275,9 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
this(null, null, null, null);
}
private DefaultCacheConfig(String[] cacheNames, String keyGenerator, String cacheManager, String cacheResolver) {
private DefaultCacheConfig(@Nullable String[] cacheNames, @Nullable String keyGenerator,
@Nullable String cacheManager, @Nullable String cacheResolver) {
this.cacheNames = cacheNames;
this.keyGenerator = keyGenerator;
this.cacheManager = cacheManager;

View File

@@ -138,36 +138,31 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
@SuppressWarnings("unchecked")
@Override
@Nullable
public <T> T get(@Nullable Object key, Callable<T> valueLoader) {
if (this.store.containsKey(key)) {
return (T) get(key).get();
}
else {
return (T) fromStoreValue(this.store.computeIfAbsent(key, r -> {
try {
return toStoreValue(valueLoader.call());
}
catch (Throwable ex) {
throw new ValueRetrievalException(key, valueLoader, ex);
}
}));
}
public <T> T get(Object key, Callable<T> valueLoader) {
return (T) fromStoreValue(this.store.computeIfAbsent(key, r -> {
try {
return toStoreValue(valueLoader.call());
}
catch (Throwable ex) {
throw new ValueRetrievalException(key, valueLoader, ex);
}
}));
}
@Override
public void put(@Nullable Object key, @Nullable Object value) {
public void put(Object key, @Nullable Object value) {
this.store.put(key, toStoreValue(value));
}
@Override
@Nullable
public ValueWrapper putIfAbsent(@Nullable Object key, @Nullable Object value) {
public ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
Object existing = this.store.putIfAbsent(key, toStoreValue(value));
return toValueWrapper(existing);
}
@Override
public void evict(@Nullable Object key) {
public void evict(Object key) {
this.store.remove(key);
}
@@ -205,7 +200,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
}
@Override
protected Object fromStoreValue(@Nullable Object storeValue) {
protected Object fromStoreValue(Object storeValue) {
if (this.serialization != null) {
try {
return super.fromStoreValue(deserializeValue(storeValue));

View File

@@ -146,7 +146,7 @@ public class ConcurrentMapCacheManager implements CacheManager, BeanClassLoaderA
}
@Override
public void setBeanClassLoader(@Nullable ClassLoader classLoader) {
public void setBeanClassLoader(ClassLoader classLoader) {
this.serialization = new SerializationDelegate(classLoader);
// Need to recreate all Cache instances with new ClassLoader in store-by-value mode...
if (isStoreByValue()) {

View File

@@ -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.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor;
import org.springframework.cache.interceptor.CacheInterceptor;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -201,16 +202,16 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
private static void registerCacheAdvisor(Element element, ParserContext parserContext) {
if (!parserContext.getRegistry().containsBeanDefinition(CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME)) {
Object eleSource = parserContext.extractSource(element);
Object source = parserContext.extractSource(element);
// Create the CacheOperationSource definition.
BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, eleSource);
BeanDefinition sourceDef = createJCacheOperationSourceBeanDefinition(element, source);
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// Create the CacheInterceptor definition.
RootBeanDefinition interceptorDef =
new RootBeanDefinition("org.springframework.cache.jcache.interceptor.JCacheInterceptor");
interceptorDef.setSource(eleSource);
interceptorDef.setSource(source);
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
interceptorDef.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(sourceName));
parseErrorHandler(element, interceptorDef);
@@ -219,7 +220,7 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
// Create the CacheAdvisor definition.
RootBeanDefinition advisorDef = new RootBeanDefinition(
"org.springframework.cache.jcache.interceptor.BeanFactoryJCacheOperationSourceAdvisor");
advisorDef.setSource(eleSource);
advisorDef.setSource(source);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
advisorDef.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(sourceName));
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
@@ -228,7 +229,7 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
}
parserContext.getRegistry().registerBeanDefinition(CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME, advisorDef);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, CacheManagementConfigUtils.JCACHE_ADVISOR_BEAN_NAME));
@@ -252,7 +253,7 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
}
}
private static RootBeanDefinition createJCacheOperationSourceBeanDefinition(Element element, Object eleSource) {
private static RootBeanDefinition createJCacheOperationSourceBeanDefinition(Element element, @Nullable Object eleSource) {
RootBeanDefinition sourceDef =
new RootBeanDefinition("org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource");
sourceDef.setSource(eleSource);

View File

@@ -34,12 +34,11 @@ public abstract class AbstractCacheInvoker {
protected AbstractCacheInvoker() {
this(new SimpleCacheErrorHandler());
this.errorHandler = new SimpleCacheErrorHandler();
}
protected AbstractCacheInvoker(CacheErrorHandler errorHandler) {
Assert.notNull(errorHandler, "ErrorHandler must not be null");
this.errorHandler = errorHandler;
setErrorHandler(errorHandler);
}
@@ -49,6 +48,7 @@ public abstract class AbstractCacheInvoker {
* is used who throws any exception as is.
*/
public void setErrorHandler(CacheErrorHandler errorHandler) {
Assert.notNull(errorHandler, "CacheErrorHandler must not be null");
this.errorHandler = errorHandler;
}
@@ -82,7 +82,7 @@ public abstract class AbstractCacheInvoker {
* Execute {@link Cache#put(Object, Object)} on the specified {@link Cache}
* and invoke the error handler if an exception occurs.
*/
protected void doPut(Cache cache, Object key, Object result) {
protected void doPut(Cache cache, Object key, @Nullable Object result) {
try {
cache.put(key, result);
}

View File

@@ -92,9 +92,9 @@ public abstract class AbstractCacheResolver implements CacheResolver, Initializi
* <p>It is acceptable to return {@code null} to indicate that no cache could
* be resolved for this invocation.
* @param context the context of the particular invocation
* @return the cache name(s) to resolve or {@code null} if no cache should be resolved
* @return the cache name(s) to resolve, or {@code null} if no cache should be resolved
*/
@Nullable
protected abstract Collection<String> getCacheNames(@Nullable CacheOperationInvocationContext<?> context);
protected abstract Collection<String> getCacheNames(CacheOperationInvocationContext<?> context);
}

View File

@@ -122,7 +122,7 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
}
@Nullable
private Collection<CacheOperation> computeCacheOperations(Method method, Class<?> targetClass) {
private Collection<CacheOperation> computeCacheOperations(Method method, @Nullable Class<?> targetClass) {
// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;

View File

@@ -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,7 +24,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
@@ -112,6 +111,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
/**
* Return the CacheOperationSource for this cache aspect.
*/
@Nullable
public CacheOperationSource getCacheOperationSource() {
return this.cacheOperationSource;
}
@@ -158,6 +158,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
/**
* Return the default {@link CacheResolver} that this cache aspect delegates to.
*/
@Nullable
public CacheResolver getCacheResolver() {
return this.cacheResolver;
}
@@ -177,7 +178,6 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
public void afterPropertiesSet() {
Assert.state(getCacheOperationSource() != null, "The 'cacheOperationSources' property is required: " +
"If there are no cacheable methods, then don't use a cache aspect.");
Assert.state(getErrorHandler() != null, "The 'errorHandler' property is required");
}
@Override
@@ -266,6 +266,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
}
else {
operationCacheResolver = getCacheResolver();
Assert.state(operationCacheResolver != null, "No CacheResolver/CacheManager set");
}
metadata = new CacheOperationMetadata(operation, method, targetClass,
operationKeyGenerator, operationCacheResolver);
@@ -297,13 +298,18 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
this.evaluator.clear();
}
@Nullable
protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
// Check whether aspect is enabled (to cope with cases where the AJ is pulled in automatically)
if (this.initialized) {
Class<?> targetClass = getTargetClass(target);
Collection<CacheOperation> operations = getCacheOperationSource().getCacheOperations(method, targetClass);
if (!CollectionUtils.isEmpty(operations)) {
return execute(invoker, method, new CacheOperationContexts(operations, method, args, target, targetClass));
CacheOperationSource cacheOperationSource = getCacheOperationSource();
if (cacheOperationSource != null) {
Collection<CacheOperation> operations = cacheOperationSource.getCacheOperations(method, targetClass);
if (!CollectionUtils.isEmpty(operations)) {
return execute(invoker, method,
new CacheOperationContexts(operations, method, args, target, targetClass));
}
}
}
@@ -325,13 +331,10 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
}
private Class<?> getTargetClass(Object target) {
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target);
if (targetClass == null && target != null) {
targetClass = target.getClass();
}
return targetClass;
return AopProxyUtils.ultimateTargetClass(target);
}
@Nullable
private Object execute(final CacheOperationInvoker invoker, Method method, CacheOperationContexts contexts) {
// Special handling of synchronized invocation
if (contexts.isSynchronized()) {
@@ -340,11 +343,8 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
Object key = generateKey(context, CacheOperationExpressionEvaluator.NO_RESULT);
Cache cache = context.getCaches().iterator().next();
try {
return wrapCacheValue(method, cache.get(key, new Callable<Object>() {
@Override
public Object call() throws Exception {
return unwrapReturnValue(invokeOperation(invoker));
}
return wrapCacheValue(method, cache.get(key, () -> {
return unwrapReturnValue(invokeOperation(invoker));
}));
}
catch (Cache.ValueRetrievalException ex) {
@@ -402,7 +402,8 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
return returnValue;
}
private Object wrapCacheValue(Method method, Object cacheValue) {
@Nullable
private Object wrapCacheValue(Method method, @Nullable Object cacheValue) {
if (method.getReturnType() == Optional.class &&
(cacheValue == null || cacheValue.getClass() != Optional.class)) {
return Optional.ofNullable(cacheValue);
@@ -410,6 +411,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
return cacheValue;
}
@Nullable
private Object unwrapReturnValue(Object returnValue) {
return ObjectUtils.unwrapOptional(returnValue);
}
@@ -432,7 +434,9 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
return (cachePutContexts.size() != excluded.size());
}
private void processCacheEvicts(Collection<CacheOperationContext> contexts, boolean beforeInvocation, Object result) {
private void processCacheEvicts(
Collection<CacheOperationContext> contexts, boolean beforeInvocation, @Nullable Object result) {
for (CacheOperationContext context : contexts) {
CacheEvictOperation operation = (CacheEvictOperation) context.metadata.operation;
if (beforeInvocation == operation.isBeforeInvocation() && isConditionPassing(context, result)) {
@@ -441,7 +445,9 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
}
}
private void performCacheEvict(CacheOperationContext context, CacheEvictOperation operation, Object result) {
private void performCacheEvict(
CacheOperationContext context, CacheEvictOperation operation, @Nullable Object result) {
Object key = null;
for (Cache cache : context.getCaches()) {
if (operation.isCacheWide()) {
@@ -450,7 +456,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
}
else {
if (key == null) {
key = context.generateKey(result);
key = generateKey(context, result);
}
logInvalidating(context, operation, key);
doEvict(cache, key);
@@ -499,7 +505,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
* @param putRequests the collection to update
*/
private void collectPutRequests(Collection<CacheOperationContext> contexts,
Object result, Collection<CachePutRequest> putRequests) {
@Nullable Object result, Collection<CachePutRequest> putRequests) {
for (CacheOperationContext context : contexts) {
if (isConditionPassing(context, result)) {
@@ -523,7 +529,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
return null;
}
private boolean isConditionPassing(CacheOperationContext context, Object result) {
private boolean isConditionPassing(CacheOperationContext context, @Nullable Object result) {
boolean passing = context.isConditionPassing(result);
if (!passing && logger.isTraceEnabled()) {
logger.trace("Cache condition failed on method " + context.metadata.method +
@@ -532,7 +538,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
return passing;
}
private Object generateKey(CacheOperationContext context, Object result) {
private Object generateKey(CacheOperationContext context, @Nullable Object result) {
Object key = context.generateKey(result);
if (key == null) {
throw new IllegalArgumentException("Null key returned for cache operation (maybe you are " +
@@ -686,7 +692,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
return combinedArgs;
}
protected boolean isConditionPassing(Object result) {
protected boolean isConditionPassing(@Nullable Object result) {
if (StringUtils.hasText(this.metadata.operation.getCondition())) {
EvaluationContext evaluationContext = createEvaluationContext(result);
return evaluator.condition(this.metadata.operation.getCondition(),
@@ -695,7 +701,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
return true;
}
protected boolean canPutToCache(Object value) {
protected boolean canPutToCache(@Nullable Object value) {
String unless = "";
if (this.metadata.operation instanceof CacheableOperation) {
unless = ((CacheableOperation) this.metadata.operation).getUnless();
@@ -712,10 +718,9 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
/**
* Compute the key for the given caching operation.
* @return the generated key, or {@code null} if none can be generated
*/
@Nullable
protected Object generateKey(Object result) {
protected Object generateKey(@Nullable Object result) {
if (StringUtils.hasText(this.metadata.operation.getKey())) {
EvaluationContext evaluationContext = createEvaluationContext(result);
return evaluator.key(this.metadata.operation.getKey(), this.methodCacheKey, evaluationContext);
@@ -723,7 +728,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
return this.metadata.keyGenerator.generate(this.target, this.metadata.method, this.args);
}
private EvaluationContext createEvaluationContext(Object result) {
private EvaluationContext createEvaluationContext(@Nullable Object result) {
return evaluator.createEvaluationContext(this.caches, this.metadata.method, this.args,
this.target, this.metadata.targetClass, result, beanFactory);
}
@@ -757,7 +762,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
this.key = key;
}
public void apply(Object result) {
public void apply(@Nullable Object result) {
if (this.context.canPutToCache(result)) {
for (Cache cache : this.context.getCaches()) {
doPut(cache, this.key, result);

View File

@@ -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 strategy for handling cache-related errors. In most cases, any
@@ -54,7 +55,7 @@ public interface CacheErrorHandler {
* @param value the value to associate with the key
* @see Cache#put(Object, Object)
*/
void handleCachePutError(RuntimeException exception, Cache cache, Object key, Object value);
void handleCachePutError(RuntimeException exception, Cache cache, Object key, @Nullable Object value);
/**
* Handle the given runtime exception thrown by the cache provider when

View File

@@ -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.
@@ -68,8 +68,7 @@ class CacheOperationExpressionEvaluator extends CachedExpressionEvaluator {
private final Map<ExpressionKey, Expression> unlessCache = new ConcurrentHashMap<>(64);
private final Map<AnnotatedElementKey, Method> targetMethodCache =
new ConcurrentHashMap<>(64);
private final Map<AnnotatedElementKey, Method> targetMethodCache = new ConcurrentHashMap<>(64);
/**
@@ -95,7 +94,7 @@ class CacheOperationExpressionEvaluator extends CachedExpressionEvaluator {
*/
public EvaluationContext createEvaluationContext(Collection<? extends Cache> caches,
Method method, Object[] args, Object target, Class<?> targetClass, @Nullable Object result,
BeanFactory beanFactory) {
@Nullable BeanFactory beanFactory) {
CacheExpressionRootObject rootObject = new CacheExpressionRootObject(
caches, method, args, target, targetClass);
@@ -114,16 +113,19 @@ class CacheOperationExpressionEvaluator extends CachedExpressionEvaluator {
return evaluationContext;
}
@Nullable
public Object key(String keyExpression, AnnotatedElementKey methodKey, EvaluationContext evalContext) {
return getExpression(this.keyCache, methodKey, keyExpression).getValue(evalContext);
}
public boolean condition(String conditionExpression, AnnotatedElementKey methodKey, EvaluationContext evalContext) {
return getExpression(this.conditionCache, methodKey, conditionExpression).getValue(evalContext, boolean.class);
return (Boolean.TRUE.equals(getExpression(this.conditionCache, methodKey, conditionExpression).getValue(
evalContext, Boolean.class)));
}
public boolean unless(String unlessExpression, AnnotatedElementKey methodKey, EvaluationContext evalContext) {
return getExpression(this.unlessCache, methodKey, unlessExpression).getValue(evalContext, boolean.class);
return (Boolean.TRUE.equals(getExpression(this.unlessCache, methodKey, unlessExpression).getValue(
evalContext, Boolean.class)));
}
/**
@@ -141,9 +143,6 @@ class CacheOperationExpressionEvaluator extends CachedExpressionEvaluator {
Method targetMethod = this.targetMethodCache.get(methodKey);
if (targetMethod == null) {
targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
if (targetMethod == null) {
targetMethod = method;
}
this.targetMethodCache.put(methodKey, targetMethod);
}
return targetMethod;

View File

@@ -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,13 +35,15 @@ public class NamedCacheResolver extends AbstractCacheResolver {
private Collection<String> cacheNames;
public NamedCacheResolver() {
}
public NamedCacheResolver(CacheManager cacheManager, String... cacheNames) {
super(cacheManager);
this.cacheNames = new ArrayList<>(Arrays.asList(cacheNames));
}
public NamedCacheResolver() {
}
/**
* Set the cache name(s) that this resolver should use.
@@ -51,7 +53,7 @@ public class NamedCacheResolver extends AbstractCacheResolver {
}
@Override
protected Collection<String> getCacheNames(@Nullable CacheOperationInvocationContext<?> context) {
protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
return this.cacheNames;
}

View File

@@ -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,7 +20,6 @@ import java.util.Collection;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.lang.Nullable;
/**
* A simple {@link CacheResolver} that resolves the {@link Cache} instance(s)
@@ -40,8 +39,9 @@ public class SimpleCacheResolver extends AbstractCacheResolver {
super(cacheManager);
}
@Override
protected Collection<String> getCacheNames(@Nullable CacheOperationInvocationContext<?> context) {
protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
return context.getOperation().getCacheNames();
}

View File

@@ -54,7 +54,7 @@ public abstract class AbstractValueAdaptingCache implements Cache {
@Override
@Nullable
public ValueWrapper get(@Nullable Object key) {
public ValueWrapper get(Object key) {
Object value = lookup(key);
return toValueWrapper(value);
}
@@ -62,7 +62,7 @@ public abstract class AbstractValueAdaptingCache implements Cache {
@Override
@SuppressWarnings("unchecked")
@Nullable
public <T> T get(@Nullable Object key, Class<T> type) {
public <T> T get(Object key, @Nullable Class<T> type) {
Object value = fromStoreValue(lookup(key));
if (value != null && type != null && !type.isInstance(value)) {
throw new IllegalStateException("Cached value is not of required type [" + type.getName() + "]: " + value);
@@ -85,7 +85,7 @@ public abstract class AbstractValueAdaptingCache implements Cache {
* @return the value to return to the user
*/
@Nullable
protected Object fromStoreValue(@Nullable Object storeValue) {
protected Object fromStoreValue(Object storeValue) {
if (this.allowNullValues && storeValue == NullValue.INSTANCE) {
return null;
}
@@ -118,7 +118,7 @@ public abstract class AbstractValueAdaptingCache implements Cache {
* @return the wrapped value
*/
@Nullable
protected Cache.ValueWrapper toValueWrapper(Object storeValue) {
protected Cache.ValueWrapper toValueWrapper(@Nullable Object storeValue) {
return (storeValue != null ? new SimpleValueWrapper(fromStoreValue(storeValue)) : null);
}

View File

@@ -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.
@@ -20,10 +20,10 @@ import java.util.concurrent.Callable;
import org.springframework.cache.Cache;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* A no operation {@link Cache} implementation suitable
* for disabling caching.
* A no operation {@link Cache} implementation suitable for disabling caching.
*
* <p>Will simply accept any items into the cache not actually storing them.
*
@@ -35,34 +35,40 @@ public class NoOpCache implements Cache {
private final String name;
/**
* Create a {@link NoOpCache} instance with the specified name
* @param name the name of the cache
*/
public NoOpCache(String name) {
Assert.notNull(name, "Cache name must not be null");
this.name = name;
}
@Override
public void clear() {
public String getName() {
return this.name;
}
@Override
public void evict(@Nullable Object key) {
public Object getNativeCache() {
return this;
}
@Override
public ValueWrapper get(@Nullable Object key) {
public ValueWrapper get(Object key) {
return null;
}
@Override
public <T> T get(@Nullable Object key, Class<T> type) {
public <T> T get(Object key, @Nullable Class<T> type) {
return null;
}
@Override
public <T> T get(@Nullable Object key, Callable<T> valueLoader) {
public <T> T get(Object key, Callable<T> valueLoader) {
try {
return valueLoader.call();
}
@@ -72,23 +78,21 @@ public class NoOpCache implements Cache {
}
@Override
public String getName() {
return this.name;
}
@Override
public Object getNativeCache() {
return null;
}
@Override
public void put(@Nullable Object key, @Nullable Object value) {
public void put(Object key, @Nullable Object value) {
}
@Override
@Nullable
public ValueWrapper putIfAbsent(@Nullable Object key, @Nullable Object value) {
public ValueWrapper putIfAbsent(Object key, @Nullable Object value) {
return null;
}
@Override
public void evict(Object key) {
}
@Override
public void clear() {
}
}

View File

@@ -37,6 +37,7 @@ public interface MessageSourceResolvable {
* they should get tried. The last code will therefore be the default one.
* @return a String array of codes which are associated with this message
*/
@Nullable
String[] getCodes();
/**

View File

@@ -74,6 +74,6 @@ public interface ResourceLoaderAware extends Aware {
* @see org.springframework.core.io.support.ResourcePatternResolver
* @see org.springframework.core.io.support.ResourcePatternUtils#getResourcePatternResolver
*/
void setResourceLoader(@Nullable ResourceLoader resourceLoader);
void setResourceLoader(ResourceLoader resourceLoader);
}

View File

@@ -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.
@@ -21,8 +21,8 @@ import java.lang.annotation.Annotation;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Convenient base class for {@link ImportSelector} implementations that select imports
@@ -33,7 +33,6 @@ import org.springframework.lang.Nullable;
* @since 3.1
* @param <A> annotation containing {@linkplain #getAdviceModeAttributeName() AdviceMode attribute}
*/
@NonNullApi
public abstract class AdviceModeImportSelector<A extends Annotation> implements ImportSelector {
public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode";
@@ -62,12 +61,14 @@ public abstract class AdviceModeImportSelector<A extends Annotation> implements
*/
@Override
public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
Class<?> annoType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
if (attributes == null) {
throw new IllegalArgumentException(String.format(
"@%s is not present on importing class '%s' as expected",
annoType.getSimpleName(), importingClassMetadata.getClassName()));
annType.getSimpleName(), importingClassMetadata.getClassName()));
}
AdviceMode adviceMode = attributes.getEnum(this.getAdviceModeAttributeName());

View File

@@ -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.
@@ -30,7 +30,6 @@ import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -46,7 +45,6 @@ import org.springframework.util.Assert;
* @since 3.0
* @see AnnotationConfigApplicationContext#register
*/
@NonNullApi
public class AnnotatedBeanDefinitionReader {
private final BeanDefinitionRegistry registry;
@@ -111,7 +109,7 @@ public class AnnotatedBeanDefinitionReader {
* Set the BeanNameGenerator to use for detected bean classes.
* <p>The default is a {@link AnnotationBeanNameGenerator}.
*/
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
public void setBeanNameGenerator(@Nullable BeanNameGenerator beanNameGenerator) {
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
}
@@ -119,7 +117,7 @@ public class AnnotatedBeanDefinitionReader {
* Set the ScopeMetadataResolver to use for detected bean classes.
* <p>The default is an {@link AnnotationScopeMetadataResolver}.
*/
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
public void setScopeMetadataResolver(@Nullable ScopeMetadataResolver scopeMetadataResolver) {
this.scopeMetadataResolver =
(scopeMetadataResolver != null ? scopeMetadataResolver : new AnnotationScopeMetadataResolver());
}
@@ -239,10 +237,8 @@ public class AnnotatedBeanDefinitionReader {
}
}
}
if (definitionCustomizers != null) {
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

View File

@@ -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.
@@ -26,8 +26,8 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -61,7 +61,6 @@ import org.springframework.util.StringUtils;
* @see org.springframework.stereotype.Controller#value()
* @see javax.inject.Named#value()
*/
@NonNullApi
public class AnnotationBeanNameGenerator implements BeanNameGenerator {
private static final String COMPONENT_ANNOTATION_CLASSNAME = "org.springframework.stereotype.Component";
@@ -92,7 +91,7 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
String beanName = null;
for (String type : types) {
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
if (isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {
if (attributes != null && isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {
Object value = attributes.get("value");
if (value instanceof String) {
String strVal = (String) value;
@@ -118,10 +117,10 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
* @return whether the annotation qualifies as a stereotype with component name
*/
protected boolean isStereotypeWithNameValue(String annotationType,
Set<String> metaAnnotationTypes, Map<String, Object> attributes) {
Set<String> metaAnnotationTypes, @Nullable Map<String, Object> attributes) {
boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) ||
(metaAnnotationTypes != null && metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME)) ||
metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) ||
annotationType.equals("javax.annotation.ManagedBean") ||
annotationType.equals("javax.inject.Named");
@@ -135,7 +134,6 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
* @param registry the registry that the given bean definition is being registered with
* @return the default bean name (never {@code null})
*/
@Nullable
protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
return buildDefaultBeanName(definition);
}
@@ -150,9 +148,10 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
* @param definition the bean definition to build a bean name for
* @return the default bean name (never {@code null})
*/
@Nullable
protected String buildDefaultBeanName(BeanDefinition definition) {
String shortClassName = ClassUtils.getShortName(definition.getBeanClassName());
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
String shortClassName = ClassUtils.getShortName(beanClassName);
return Introspector.decapitalize(shortClassName);
}

View File

@@ -23,7 +23,6 @@ import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -51,7 +50,6 @@ import org.springframework.util.Assert;
* @see ClassPathBeanDefinitionScanner
* @see org.springframework.context.support.GenericXmlApplicationContext
*/
@NonNullApi
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
@@ -190,7 +188,7 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
* (may be {@code null} or empty)
* @since 5.0
*/
public <T> void registerBean(Class<T> annotatedClass, @Nullable Object... constructorArguments) {
public <T> void registerBean(Class<T> annotatedClass, Object... constructorArguments) {
registerBean(null, annotatedClass, constructorArguments);
}
@@ -206,7 +204,7 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
* (may be {@code null} or empty)
* @since 5.0
*/
public <T> void registerBean(@Nullable String beanName, Class<T> annotatedClass, @Nullable Object... constructorArguments) {
public <T> void registerBean(@Nullable String beanName, Class<T> annotatedClass, Object... constructorArguments) {
this.reader.doRegisterBean(annotatedClass, null, beanName, null,
bd -> {
for (Object arg : constructorArguments) {
@@ -216,7 +214,7 @@ public class AnnotationConfigApplicationContext extends GenericApplicationContex
}
@Override
public <T> void registerBean(@Nullable String beanName, @Nullable Class<T> beanClass, @Nullable Supplier<T> supplier,
public <T> void registerBean(@Nullable String beanName, Class<T> beanClass, @Nullable Supplier<T> supplier,
BeanDefinitionCustomizer... customizers) {
this.reader.doRegisterBean(beanClass, supplier, beanName, null, customizers);

View File

@@ -26,7 +26,6 @@ import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.lang.NonNullApi;
/**
* Parser for the &lt;context:annotation-config/&gt; element.
@@ -37,7 +36,6 @@ import org.springframework.lang.NonNullApi;
* @since 2.5
* @see AnnotationConfigUtils
*/
@NonNullApi
public class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser {
@Override

View File

@@ -16,8 +16,6 @@
package org.springframework.context.annotation;
import org.springframework.lang.NonNullApi;
/**
* Common interface for annotation config application contexts,
* defining {@link #register} and {@link #scan} methods.
@@ -25,7 +23,6 @@ import org.springframework.lang.NonNullApi;
* @author Juergen Hoeller
* @since 4.1
*/
@NonNullApi
public interface AnnotationConfigRegistry {
/**

View File

@@ -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.
@@ -37,7 +37,6 @@ import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
@@ -61,7 +60,6 @@ import org.springframework.util.ClassUtils;
* @see org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor
* @see org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
*/
@NonNullApi
public class AnnotationConfigUtils {
/**
@@ -240,27 +238,34 @@ public class AnnotationConfigUtils {
}
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
if (metadata.isAnnotated(Lazy.class.getName())) {
abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value"));
AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
else if (abd.getMetadata() != metadata && abd.getMetadata().isAnnotated(Lazy.class.getName())) {
abd.setLazyInit(attributesFor(abd.getMetadata(), Lazy.class).getBoolean("value"));
else if (abd.getMetadata() != metadata) {
lazy = attributesFor(abd.getMetadata(), Lazy.class);
if (lazy != null) {
abd.setLazyInit(lazy.getBoolean("value"));
}
}
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
if (metadata.isAnnotated(DependsOn.class.getName())) {
abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value"));
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
abd.setDependsOn(dependsOn.getStringArray("value"));
}
if (abd instanceof AbstractBeanDefinition) {
AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
if (metadata.isAnnotated(Role.class.getName())) {
absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue());
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
absBd.setRole(role.getNumber("value").intValue());
}
if (metadata.isAnnotated(Description.class.getName())) {
absBd.setDescription(attributesFor(metadata, Description.class).getString("value"));
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
absBd.setDescription(description.getString("value"));
}
}
}
@@ -276,10 +281,12 @@ public class AnnotationConfigUtils {
return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
@Nullable
static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, Class<?> annotationClass) {
return attributesFor(metadata, annotationClass.getName());
}
@Nullable
static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annotationClassName) {
return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName, false));
}
@@ -306,7 +313,9 @@ public class AnnotationConfigUtils {
return Collections.unmodifiableSet(result);
}
private static void addAttributesIfNotNull(Set<AnnotationAttributes> result, Map<String, Object> attributes) {
private static void addAttributesIfNotNull(
Set<AnnotationAttributes> result, @Nullable Map<String, Object> attributes) {
if (attributes != null) {
result.add(AnnotationAttributes.fromMap(attributes));
}

View File

@@ -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.
@@ -21,7 +21,6 @@ import java.lang.annotation.Annotation;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.lang.NonNullApi;
import org.springframework.util.Assert;
/**
@@ -37,7 +36,6 @@ import org.springframework.util.Assert;
* @since 2.5
* @see org.springframework.context.annotation.Scope
*/
@NonNullApi
public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {
private final ScopedProxyMode defaultProxyMode;
@@ -86,7 +84,7 @@ public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {
if (attributes != null) {
metadata.setScopeName(attributes.getString("value"));
ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) {
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = this.defaultProxyMode;
}
metadata.setScopedProxyMode(proxyMode);

View File

@@ -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.
@@ -20,7 +20,6 @@ import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
/**
* Registers an {@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
@@ -32,7 +31,6 @@ import org.springframework.lang.NonNullApi;
* @since 3.1
* @see EnableAspectJAutoProxy
*/
@NonNullApi
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
@@ -48,11 +46,13 @@ class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}

View File

@@ -25,7 +25,6 @@ import org.springframework.aop.config.AopConfigUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
/**
* Registers an auto proxy creator against the current {@link BeanDefinitionRegistry}
@@ -36,7 +35,6 @@ import org.springframework.lang.NonNullApi;
* @since 3.1
* @see EnableAspectJAutoProxy
*/
@NonNullApi
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
private final Log logger = LogFactory.getLog(getClass());

View File

@@ -19,7 +19,6 @@ package org.springframework.context.annotation;
import java.lang.reflect.Method;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.NonNullApi;
/**
* Utilities for processing {@link Bean}-annotated methods.
@@ -28,7 +27,6 @@ import org.springframework.lang.NonNullApi;
* @author Juergen Hoeller
* @since 3.1
*/
@NonNullApi
class BeanAnnotationHelper {
public static boolean isBeanAnnotated(Method method) {

View File

@@ -19,7 +19,6 @@ package org.springframework.context.annotation;
import org.springframework.beans.factory.parsing.Problem;
import org.springframework.beans.factory.parsing.ProblemReporter;
import org.springframework.core.type.MethodMetadata;
import org.springframework.lang.NonNullApi;
/**
* Represents a {@link Configuration} class method marked with the
@@ -32,7 +31,6 @@ import org.springframework.lang.NonNullApi;
* @see ConfigurationClassParser
* @see ConfigurationClassBeanDefinitionReader
*/
@NonNullApi
final class BeanMethod extends ConfigurationMethod {
public BeanMethod(MethodMetadata metadata, ConfigurationClass configurationClass) {

View File

@@ -31,7 +31,7 @@ import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;
@@ -60,7 +60,6 @@ import org.springframework.util.PatternMatchUtils;
* @see org.springframework.stereotype.Service
* @see org.springframework.stereotype.Controller
*/
@NonNullApi
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
private final BeanDefinitionRegistry registry;
@@ -157,7 +156,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
* @since 4.3.6
*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, ResourceLoader resourceLoader) {
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
@@ -181,7 +180,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
* Set the defaults to use for detected beans.
* @see BeanDefinitionDefaults
*/
public void setBeanDefinitionDefaults(BeanDefinitionDefaults beanDefinitionDefaults) {
public void setBeanDefinitionDefaults(@Nullable BeanDefinitionDefaults beanDefinitionDefaults) {
this.beanDefinitionDefaults =
(beanDefinitionDefaults != null ? beanDefinitionDefaults : new BeanDefinitionDefaults());
}
@@ -198,7 +197,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
* Set the name-matching patterns for determining autowire candidates.
* @param autowireCandidatePatterns the patterns to match against
*/
public void setAutowireCandidatePatterns(String... autowireCandidatePatterns) {
public void setAutowireCandidatePatterns(@Nullable String... autowireCandidatePatterns) {
this.autowireCandidatePatterns = autowireCandidatePatterns;
}
@@ -206,7 +205,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
* Set the BeanNameGenerator to use for detected bean classes.
* <p>Default is a {@link AnnotationBeanNameGenerator}.
*/
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
public void setBeanNameGenerator(@Nullable BeanNameGenerator beanNameGenerator) {
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
}
@@ -216,7 +215,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
* <p>The default is an {@link AnnotationScopeMetadataResolver}.
* @see #setScopedProxyMode
*/
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
public void setScopeMetadataResolver(@Nullable ScopeMetadataResolver scopeMetadataResolver) {
this.scopeMetadataResolver =
(scopeMetadataResolver != null ? scopeMetadataResolver : new AnnotationScopeMetadataResolver());
}
@@ -360,7 +359,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
*/
protected boolean isCompatible(BeanDefinition newDefinition, BeanDefinition existingDefinition) {
return (!(existingDefinition instanceof ScannedGenericBeanDefinition) || // explicitly registered overriding bean
newDefinition.getSource().equals(existingDefinition.getSource()) || // scanned same file twice
(newDefinition.getSource() != null && newDefinition.getSource().equals(existingDefinition.getSource())) || // scanned same file twice
newDefinition.equals(existingDefinition)); // scanned equivalent class twice
}

View File

@@ -51,7 +51,6 @@ import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
@@ -85,7 +84,6 @@ import org.springframework.util.ClassUtils;
* @see ScannedGenericBeanDefinition
* @see CandidateComponentsIndex
*/
@NonNullApi
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";

View File

@@ -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.
@@ -65,7 +65,7 @@ import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.Ordered;
import org.springframework.jndi.support.SimpleJndiBeanFactory;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
@@ -140,7 +140,6 @@ import org.springframework.util.StringValueResolver;
* @see org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
*/
@SuppressWarnings("serial")
@NonNullApi
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
@@ -295,10 +294,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
if (beanType != null) {
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
@Override
@@ -326,7 +323,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, PropertyValues pvs) {
private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
@@ -443,7 +440,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
* @see #getResource
* @see Lazy
*/
protected Object buildLazyResourceProxy(final LookupElement element, final String requestingBeanName) {
protected Object buildLazyResourceProxy(final LookupElement element, final @Nullable String requestingBeanName) {
TargetSource ts = new TargetSource() {
@Override
public Class<?> getTargetClass() {
@@ -478,7 +475,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
* @return the resource object (never {@code null})
* @throws BeansException if we failed to obtain the target resource
*/
protected Object getResource(LookupElement element, String requestingBeanName) throws BeansException {
protected Object getResource(LookupElement element, @Nullable String requestingBeanName) throws BeansException {
if (StringUtils.hasLength(element.mappedName)) {
return this.jndiFactory.getBean(element.mappedName, element.lookupType);
}
@@ -501,7 +498,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
* @return the resource object (never {@code null})
* @throws BeansException if we failed to obtain the target resource
*/
protected Object autowireResource(BeanFactory factory, LookupElement element, String requestingBeanName)
protected Object autowireResource(BeanFactory factory, LookupElement element, @Nullable String requestingBeanName)
throws BeansException {
Object resource;
@@ -513,6 +510,9 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
autowiredBeanNames = new LinkedHashSet<>();
resource = ((AutowireCapableBeanFactory) factory).resolveDependency(
element.getDependencyDescriptor(), requestingBeanName, autowiredBeanNames, null);
if (resource == null) {
throw new NoSuchBeanDefinitionException(element.getLookupType(), "No resolvable resource object");
}
}
else {
resource = factory.getBean(name, element.lookupType);
@@ -522,7 +522,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
if (factory instanceof ConfigurableBeanFactory) {
ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
for (String autowiredBeanName : autowiredBeanNames) {
if (beanFactory.containsBean(autowiredBeanName)) {
if (requestingBeanName != null && beanFactory.containsBean(autowiredBeanName)) {
beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);
}
}
@@ -546,7 +546,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
protected String mappedName;
public LookupElement(Member member, PropertyDescriptor pd) {
public LookupElement(Member member, @Nullable PropertyDescriptor pd) {
super(member, pd);
}
@@ -586,7 +586,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private final boolean lazyLookup;
public ResourceElement(Member member, AnnotatedElement ae, PropertyDescriptor pd) {
public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
super(member, pd);
Resource resource = ae.getAnnotation(Resource.class);
String resourceName = resource.name();
@@ -618,7 +618,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
@Override
protected Object getResourceToInject(Object target, String requestingBeanName) {
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
getResource(this, requestingBeanName));
}
@@ -635,7 +635,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private final String wsdlLocation;
public WebServiceRefElement(Member member, AnnotatedElement ae, PropertyDescriptor pd) {
public WebServiceRefElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
super(member, pd);
WebServiceRef resource = ae.getAnnotation(WebServiceRef.class);
String resourceName = resource.name();
@@ -667,7 +667,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
@Override
protected Object getResourceToInject(Object target, String requestingBeanName) {
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
Service service;
try {
service = (Service) getResource(this, requestingBeanName);
@@ -718,7 +718,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private final String beanName;
public EjbRefElement(Member member, AnnotatedElement ae, PropertyDescriptor pd) {
public EjbRefElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
super(member, pd);
EJB resource = ae.getAnnotation(EJB.class);
String resourceBeanName = resource.beanName();
@@ -745,12 +745,12 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
@Override
protected Object getResourceToInject(Object target, String requestingBeanName) {
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
if (StringUtils.hasLength(this.beanName)) {
if (beanFactory != null && beanFactory.containsBean(this.beanName)) {
// Local match found for explicitly specified local bean name.
Object bean = beanFactory.getBean(this.beanName, this.lookupType);
if (beanFactory instanceof ConfigurableBeanFactory) {
if (requestingBeanName != null && beanFactory instanceof ConfigurableBeanFactory) {
((ConfigurableBeanFactory) beanFactory).registerDependentBean(this.beanName, requestingBeanName);
}
return bean;

View File

@@ -38,7 +38,7 @@ import org.springframework.core.type.filter.AspectJTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -53,7 +53,6 @@ import org.springframework.util.StringUtils;
* @see ClassPathBeanDefinitionScanner#scan(String...)
* @see ComponentScanBeanDefinitionParser
*/
@NonNullApi
class ComponentScanAnnotationParser {
private final Environment environment;
@@ -65,11 +64,11 @@ class ComponentScanAnnotationParser {
private final BeanDefinitionRegistry registry;
public ComponentScanAnnotationParser(Environment environment, ResourceLoader resourceLoader,
public ComponentScanAnnotationParser(@Nullable Environment environment, @Nullable ResourceLoader resourceLoader,
BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry) {
this.resourceLoader = resourceLoader;
this.environment = environment;
this.resourceLoader = resourceLoader;
this.beanNameGenerator = beanNameGenerator;
this.registry = registry;
}

View File

@@ -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.
@@ -40,7 +40,8 @@ import org.springframework.core.type.filter.AspectJTypeFilter;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.RegexPatternTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
@@ -52,7 +53,6 @@ import org.springframework.util.StringUtils;
* @author Juergen Hoeller
* @since 2.5
*/
@NonNullApi
public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
private static final String BASE_PACKAGE_ATTRIBUTE = "base-package";
@@ -224,16 +224,18 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
}
@SuppressWarnings("unchecked")
protected TypeFilter createTypeFilter(Element element, ClassLoader classLoader, ParserContext parserContext) {
protected TypeFilter createTypeFilter(
Element element, @Nullable ClassLoader classLoader, ParserContext parserContext) {
String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE);
String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE);
expression = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(expression);
try {
if ("annotation".equals(filterType)) {
return new AnnotationTypeFilter((Class<Annotation>) classLoader.loadClass(expression));
return new AnnotationTypeFilter((Class<Annotation>) ClassUtils.forName(expression, classLoader));
}
else if ("assignable".equals(filterType)) {
return new AssignableTypeFilter(classLoader.loadClass(expression));
return new AssignableTypeFilter(ClassUtils.forName(expression, classLoader));
}
else if ("aspectj".equals(filterType)) {
return new AspectJTypeFilter(expression, classLoader);
@@ -242,7 +244,7 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
return new RegexPatternTypeFilter(Pattern.compile(expression));
}
else if ("custom".equals(filterType)) {
Class<?> filterClass = classLoader.loadClass(expression);
Class<?> filterClass = ClassUtils.forName(expression, classLoader);
if (!TypeFilter.class.isAssignableFrom(filterClass)) {
throw new IllegalArgumentException(
"Class is not assignable to [" + TypeFilter.class.getName() + "]: " + expression);
@@ -259,10 +261,12 @@ public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
}
@SuppressWarnings("unchecked")
private Object instantiateUserDefinedStrategy(String className, Class<?> strategyType, ClassLoader classLoader) {
private Object instantiateUserDefinedStrategy(
String className, Class<?> strategyType, @Nullable ClassLoader classLoader) {
Object result;
try {
result = ReflectionUtils.accessibleConstructor(classLoader.loadClass(className)).newInstance();
result = ReflectionUtils.accessibleConstructor(ClassUtils.forName(className, classLoader)).newInstance();
}
catch (ClassNotFoundException ex) {
throw new IllegalArgumentException("Class [" + className + "] for strategy [" +

View File

@@ -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,7 +18,6 @@ package org.springframework.context.annotation;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.lang.NonNullApi;
/**
* A single {@code condition} that must be {@linkplain #matches matched} in order
@@ -40,16 +39,15 @@ import org.springframework.lang.NonNullApi;
* @see ConditionContext
*/
@FunctionalInterface
@NonNullApi
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
* or {@link org.springframework.core.type.MethodMetadata method} being checked.
* @return {@code true} if the condition matches and the component can be registered
* or {@code false} to veto registration.
* or {@link org.springframework.core.type.MethodMetadata method} being checked
* @return {@code true} if the condition matches and the component can be registered,
* or {@code false} to veto the annotated component's registration
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);

View File

@@ -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.
@@ -25,43 +25,35 @@ import org.springframework.core.io.ResourceLoader;
* Context information for use by {@link Condition}s.
*
* @author Phillip Webb
* @author Juergen Hoeller
* @since 4.0
*/
public interface ConditionContext {
/**
* Return the {@link BeanDefinitionRegistry} that will hold the bean definition
* should the condition match or {@code null} if the registry is not available.
* @return the registry or {@code null}
* should the condition match.
*/
BeanDefinitionRegistry getRegistry();
/**
* Return the {@link ConfigurableListableBeanFactory} that will hold the bean
* definition should the condition match or {@code null} if the bean factory
* is not available.
* @return the bean factory or {@code null}
* definition should the condition match.
*/
ConfigurableListableBeanFactory getBeanFactory();
/**
* Return the {@link Environment} for which the current application is running
* or {@code null} if no environment is available.
* @return the environment or {@code null}
* Return the {@link Environment} for which the current application is running.
*/
Environment getEnvironment();
/**
* Return the {@link ResourceLoader} currently being used or {@code null}
* if the resource loader cannot be obtained.
* @return a resource loader or {@code null}
* Return the {@link ResourceLoader} currently being used.
*/
ResourceLoader getResourceLoader();
/**
* Return the {@link ClassLoader} that should be used to load additional
* classes or {@code null} if the default classloader should be used.
* @return the class loader or {@code null}
* Return the {@link ClassLoader} that should be used to load additional classes.
*/
ClassLoader getClassLoader();

View File

@@ -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,11 +28,13 @@ import org.springframework.context.annotation.ConfigurationCondition.Configurati
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.core.env.Environment;
import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.MultiValueMap;
@@ -40,9 +42,9 @@ import org.springframework.util.MultiValueMap;
* Internal class used to evaluate {@link Conditional} annotations.
*
* @author Phillip Webb
* @author Juergen Hoeller
* @since 4.0
*/
@NonNullApi
class ConditionEvaluator {
private final ConditionContextImpl context;
@@ -51,7 +53,9 @@ class ConditionEvaluator {
/**
* Create a new {@link ConditionEvaluator} instance.
*/
public ConditionEvaluator(BeanDefinitionRegistry registry, Environment environment, ResourceLoader resourceLoader) {
public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
this.context = new ConditionContextImpl(registry, environment, resourceLoader);
}
@@ -73,7 +77,7 @@ class ConditionEvaluator {
* @param phase the phase of the call
* @return if the item should be skipped
*/
public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) {
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
return false;
}
@@ -137,15 +141,20 @@ class ConditionEvaluator {
private final ResourceLoader resourceLoader;
public ConditionContextImpl(BeanDefinitionRegistry registry, Environment environment, ResourceLoader resourceLoader) {
private final ClassLoader classLoader;
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
this.registry = registry;
this.beanFactory = deduceBeanFactory(registry);
this.environment = (environment != null ? environment : deduceEnvironment(registry));
this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
}
@Nullable
private ConfigurableListableBeanFactory deduceBeanFactory(BeanDefinitionRegistry source) {
private ConfigurableListableBeanFactory deduceBeanFactory(@Nullable BeanDefinitionRegistry source) {
if (source instanceof ConfigurableListableBeanFactory) {
return (ConfigurableListableBeanFactory) source;
}
@@ -155,29 +164,45 @@ class ConditionEvaluator {
return null;
}
@Nullable
private Environment deduceEnvironment(BeanDefinitionRegistry source) {
private Environment deduceEnvironment(@Nullable BeanDefinitionRegistry source) {
if (source instanceof EnvironmentCapable) {
return ((EnvironmentCapable) source).getEnvironment();
}
return null;
return new StandardEnvironment();
}
@Nullable
private ResourceLoader deduceResourceLoader(BeanDefinitionRegistry source) {
private ResourceLoader deduceResourceLoader(@Nullable BeanDefinitionRegistry source) {
if (source instanceof ResourceLoader) {
return (ResourceLoader) source;
}
return null;
return new DefaultResourceLoader();
}
@Nullable
private ClassLoader deduceClassLoader(@Nullable ResourceLoader resourceLoader,
@Nullable ConfigurableListableBeanFactory beanFactory) {
if (resourceLoader != null) {
ClassLoader classLoader = resourceLoader.getClassLoader();
if (classLoader != null) {
return classLoader;
}
}
if (beanFactory != null) {
return beanFactory.getBeanClassLoader();
}
return ClassUtils.getDefaultClassLoader();
}
@Override
public BeanDefinitionRegistry getRegistry() {
Assert.state(this.registry != null, "No BeanDefinitionRegistry available");
return this.registry;
}
@Override
public ConfigurableListableBeanFactory getBeanFactory() {
Assert.state(this.beanFactory != null, "No ConfigurableListableBeanFactory available");
return this.beanFactory;
}
@@ -193,13 +218,8 @@ class ConditionEvaluator {
@Override
public ClassLoader getClassLoader() {
if (this.resourceLoader != null) {
return this.resourceLoader.getClassLoader();
}
if (this.beanFactory != null) {
return this.beanFactory.getBeanClassLoader();
}
return null;
Assert.state(this.classLoader != null, "No ClassLoader available");
return this.classLoader;
}
}

View File

@@ -31,7 +31,6 @@ import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -48,7 +47,6 @@ import org.springframework.util.ClassUtils;
* @see BeanMethod
* @see ConfigurationClassParser
*/
@NonNullApi
final class ConfigurationClass {
private final AnnotationMetadata metadata;

View File

@@ -50,7 +50,7 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.lang.NonNullApi;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -68,7 +68,6 @@ import org.springframework.util.StringUtils;
* @since 3.0
* @see ConfigurationClassParser
*/
@NonNullApi
class ConfigurationClassBeanDefinitionReader {
private static final Log logger = LogFactory.getLog(ConfigurationClassBeanDefinitionReader.class);
@@ -185,8 +184,10 @@ class ConfigurationClassBeanDefinitionReader {
return;
}
// Consider name and any aliases
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
Assert.state(bean != null, "No @Bean annotation attributes");
// Consider name and any aliases
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
@@ -230,9 +231,7 @@ class ConfigurationClassBeanDefinitionReader {
}
String destroyMethodName = bean.getString("destroyMethod");
if (destroyMethodName != null) {
beanDef.setDestroyMethodName(destroyMethodName);
}
beanDef.setDestroyMethodName(destroyMethodName);
// Consider scoping
ScopedProxyMode proxyMode = ScopedProxyMode.NO;

View File

@@ -17,7 +17,6 @@
package org.springframework.context.annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
@@ -49,7 +48,6 @@ import org.springframework.cglib.proxy.NoOp;
import org.springframework.cglib.transform.ClassEmitterTransformer;
import org.springframework.cglib.transform.TransformingClassGenerator;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.objenesis.ObjenesisException;
import org.springframework.objenesis.SpringObjenesis;
@@ -73,7 +71,6 @@ import org.springframework.util.ReflectionUtils;
* @see #enhance
* @see ConfigurationClassPostProcessor
*/
@NonNullApi
class ConfigurationClassEnhancer {
// The callbacks to use. Note that these callbacks must be stateless.
@@ -215,7 +212,7 @@ class ConfigurationClassEnhancer {
private final ClassLoader classLoader;
public BeanFactoryAwareGeneratorStrategy(ClassLoader classLoader) {
public BeanFactoryAwareGeneratorStrategy(@Nullable ClassLoader classLoader) {
this.classLoader = classLoader;
}
@@ -391,7 +388,7 @@ class ConfigurationClassEnhancer {
}
Object beanInstance = (useArgs ? beanFactory.getBean(beanName, beanMethodArgs) :
beanFactory.getBean(beanName));
if (beanInstance != null && !ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
if (!ClassUtils.isAssignableValue(beanMethod.getReturnType(), beanInstance)) {
String msg = String.format("@Bean method %s.%s called as a bean reference " +
"for type [%s] but overridden by non-compatible bean instance of type [%s].",
beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName(),
@@ -511,14 +508,11 @@ class ConfigurationClassEnhancer {
return Proxy.newProxyInstance(
factoryBean.getClass().getClassLoader(), new Class<?>[] {interfaceType},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("getObject") && args == null) {
return beanFactory.getBean(beanName);
}
return ReflectionUtils.invokeMethod(method, factoryBean, args);
(proxy, method, args) -> {
if (method.getName().equals("getObject") && args == null) {
return beanFactory.getBean(beanName);
}
return ReflectionUtils.invokeMethod(method, factoryBean, args);
});
}

View File

@@ -72,9 +72,9 @@ import org.springframework.core.type.StandardAnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -101,18 +101,12 @@ import org.springframework.util.StringUtils;
* @since 3.0
* @see ConfigurationClassBeanDefinitionReader
*/
@NonNullApi
class ConfigurationClassParser {
private static final PropertySourceFactory DEFAULT_PROPERTY_SOURCE_FACTORY = new DefaultPropertySourceFactory();
private static final Comparator<DeferredImportSelectorHolder> DEFERRED_IMPORT_COMPARATOR =
new Comparator<ConfigurationClassParser.DeferredImportSelectorHolder>() {
@Override
public int compare(DeferredImportSelectorHolder o1, DeferredImportSelectorHolder o2) {
return AnnotationAwareOrderComparator.INSTANCE.compare(o1.getImportSelector(), o2.getImportSelector());
}
};
(o1, o2) -> AnnotationAwareOrderComparator.INSTANCE.compare(o1.getImportSelector(), o2.getImportSelector());
private final Log logger = LogFactory.getLog(getClass());
@@ -189,7 +183,8 @@ class ConfigurationClassParser {
processDeferredImportSelectors();
}
protected final void parse(String className, String beanName) throws IOException {
protected final void parse(@Nullable String className, String beanName) throws IOException {
Assert.notNull(className, "No bean class name for configuration class bean definition");
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
processConfigurationClass(new ConfigurationClass(reader, beanName));
}
@@ -304,9 +299,9 @@ class ConfigurationClassParser {
processImports(configClass, sourceClass, getImports(sourceClass), true);
// Process any @ImportResource annotations
if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
@@ -327,7 +322,8 @@ class ConfigurationClassParser {
// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
@@ -469,32 +465,35 @@ class ConfigurationClassParser {
private void addPropertySource(PropertySource<?> propertySource) {
String name = propertySource.getName();
MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();
if (propertySources.contains(name) && this.propertySourceNames.contains(name)) {
if (this.propertySourceNames.contains(name)) {
// We've already added a version, we need to extend it
PropertySource<?> existing = propertySources.get(name);
PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
((ResourcePropertySource) propertySource).withResourceName() : propertySource);
if (existing instanceof CompositePropertySource) {
((CompositePropertySource) existing).addFirstPropertySource(newSource);
}
else {
if (existing instanceof ResourcePropertySource) {
existing = ((ResourcePropertySource) existing).withResourceName();
if (existing != null) {
PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
((ResourcePropertySource) propertySource).withResourceName() : propertySource);
if (existing instanceof CompositePropertySource) {
((CompositePropertySource) existing).addFirstPropertySource(newSource);
}
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(newSource);
composite.addPropertySource(existing);
propertySources.replace(name, composite);
else {
if (existing instanceof ResourcePropertySource) {
existing = ((ResourcePropertySource) existing).withResourceName();
}
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(newSource);
composite.addPropertySource(existing);
propertySources.replace(name, composite);
}
return;
}
}
if (this.propertySourceNames.isEmpty()) {
propertySources.addLast(propertySource);
}
else {
if (this.propertySourceNames.isEmpty()) {
propertySources.addLast(propertySource);
}
else {
String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
propertySources.addBefore(firstProcessed, propertySource);
}
String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
propertySources.addBefore(firstProcessed, propertySource);
}
this.propertySourceNames.add(name);
}
@@ -655,7 +654,10 @@ class ConfigurationClassParser {
/**
* Factory method to obtain a {@link SourceClass} from a {@link Class}.
*/
SourceClass asSourceClass(Class<?> classType) throws IOException {
SourceClass asSourceClass(@Nullable Class<?> classType) throws IOException {
if (classType == null) {
return new SourceClass(Object.class);
}
try {
// Sanity test that we can read annotations, if not fall back to ASM
classType.getAnnotations();
@@ -681,11 +683,14 @@ class ConfigurationClassParser {
/**
* Factory method to obtain a {@link SourceClass} from a class name.
*/
SourceClass asSourceClass(String className) throws IOException {
SourceClass asSourceClass(@Nullable String className) throws IOException {
if (className == null) {
return new SourceClass(Object.class);
}
if (className.startsWith("java")) {
// Never use ASM for core java types
try {
return new SourceClass(this.resourceLoader.getClassLoader().loadClass(className));
return new SourceClass(ClassUtils.forName(className, this.resourceLoader.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new NestedIOException("Failed to load class [" + className + "]", ex);
@@ -802,7 +807,7 @@ class ConfigurationClassParser {
return (Class<?>) this.source;
}
String className = ((MetadataReader) this.source).getClassMetadata().getClassName();
return resourceLoader.getClassLoader().loadClass(className);
return ClassUtils.forName(className, resourceLoader.getClassLoader());
}
public boolean isAssignable(Class<?> clazz) throws IOException {

View File

@@ -61,7 +61,6 @@ import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -86,7 +85,6 @@ import static org.springframework.context.annotation.AnnotationConfigUtils.*;
* @author Phillip Webb
* @since 3.0
*/
@NonNullApi
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
@@ -118,14 +116,16 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private boolean localBeanNameGeneratorSet = false;
/* using short class names as default bean names */
/* Using short class names as default bean names */
private BeanNameGenerator componentScanBeanNameGenerator = new AnnotationBeanNameGenerator();
/* using fully qualified class names as default bean names */
/* Using fully qualified class names as default bean names */
private BeanNameGenerator importBeanNameGenerator = new AnnotationBeanNameGenerator() {
@Override
protected String buildDefaultBeanName(BeanDefinition definition) {
return definition.getBeanClassName();
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
return beanClassName;
}
};
@@ -139,7 +139,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
* Set the {@link SourceExtractor} to use for generated bean definitions
* that correspond to {@link Bean} factory methods.
*/
public void setSourceExtractor(SourceExtractor sourceExtractor) {
public void setSourceExtractor(@Nullable SourceExtractor sourceExtractor) {
this.sourceExtractor = (sourceExtractor != null ? sourceExtractor : new PassThroughSourceExtractor());
}
@@ -149,7 +149,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
* declarations. For instance, an @Bean method marked as {@code final} is illegal
* and would be reported as a problem. Defaults to {@link FailFastProblemReporter}.
*/
public void setProblemReporter(ProblemReporter problemReporter) {
public void setProblemReporter(@Nullable ProblemReporter problemReporter) {
this.problemReporter = (problemReporter != null ? problemReporter : new FailFastProblemReporter());
}
@@ -204,7 +204,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
@Override
public void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) {
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
if (!this.setMetadataReaderFactoryCalled) {
this.metadataReaderFactory = new CachingMetadataReaderFactory(beanClassLoader);
@@ -293,10 +293,12 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
@@ -387,6 +389,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
// nothing to enhance -> return immediately
return;
}
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
@@ -395,13 +398,15 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
try {
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
if (configClass != null) {
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Replacing bean definition '%s' existing class '%s' with " +
"enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
}
beanDef.setBeanClass(enhancedClass);
}
beanDef.setBeanClass(enhancedClass);
}
}
catch (Throwable ex) {

View File

@@ -35,7 +35,6 @@ import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.lang.NonNullApi;
import org.springframework.stereotype.Component;
/**
@@ -45,7 +44,6 @@ import org.springframework.stereotype.Component;
* @author Juergen Hoeller
* @since 3.1
*/
@NonNullApi
abstract class ConfigurationClassUtils {
private static final String CONFIGURATION_CLASS_FULL = "full";

View File

@@ -16,8 +16,6 @@
package org.springframework.context.annotation;
import org.springframework.lang.NonNullApi;
/**
* A {@link Condition} that offers more fine-grained control when used with
* {@code @Configuration}. Allows certain {@link Condition}s to adapt when they match
@@ -29,7 +27,6 @@ import org.springframework.lang.NonNullApi;
* @since 4.0
* @see Configuration
*/
@NonNullApi
public interface ConfigurationCondition extends Condition {
/**

View File

@@ -19,13 +19,11 @@ package org.springframework.context.annotation;
import org.springframework.beans.factory.parsing.Location;
import org.springframework.beans.factory.parsing.ProblemReporter;
import org.springframework.core.type.MethodMetadata;
import org.springframework.lang.NonNullApi;
/**
* @author Chris Beams
* @since 3.1
*/
@NonNullApi
abstract class ConfigurationMethod {
protected final MethodMetadata metadata;

View File

@@ -16,8 +16,6 @@
package org.springframework.context.annotation;
import org.springframework.lang.NonNullApi;
/**
* Marker subclass of {@link IllegalStateException}, allowing for explicit
* catch clauses in calling code.
@@ -26,7 +24,6 @@ import org.springframework.lang.NonNullApi;
* @since 3.1
*/
@SuppressWarnings("serial")
@NonNullApi
class ConflictingBeanDefinitionException extends IllegalStateException {
public ConflictingBeanDefinitionException(String message) {

View File

@@ -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.
@@ -27,7 +27,7 @@ import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -39,11 +39,10 @@ import org.springframework.util.Assert;
* @author Juergen Hoeller
* @since 4.0
*/
@NonNullApi
public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotationAutowireCandidateResolver {
@Override
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, String beanName) {
public Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor, @Nullable String beanName) {
return (isLazy(descriptor) ? buildLazyResolutionProxy(descriptor, beanName) : null);
}
@@ -67,7 +66,7 @@ public class ContextAnnotationAutowireCandidateResolver extends QualifierAnnotat
return false;
}
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final String beanName) {
protected Object buildLazyResolutionProxy(final DependencyDescriptor descriptor, final @Nullable String beanName) {
Assert.state(getBeanFactory() instanceof DefaultListableBeanFactory,
"BeanFactory needs to be a DefaultListableBeanFactory");
final DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) getBeanFactory();

View File

@@ -16,8 +16,6 @@
package org.springframework.context.annotation;
import org.springframework.lang.NonNullApi;
/**
* A variation of {@link ImportSelector} that runs after all {@code @Configuration} beans
* have been processed. This type of selector can be particularly useful when the selected
@@ -30,7 +28,6 @@ import org.springframework.lang.NonNullApi;
* @author Phillip Webb
* @since 4.0
*/
@NonNullApi
public interface DeferredImportSelector extends ImportSelector {
}

View File

@@ -18,7 +18,6 @@ package org.springframework.context.annotation;
import org.springframework.beans.factory.Aware;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
/**
* Interface to be implemented by any @{@link Configuration} class that wishes
@@ -29,7 +28,6 @@ import org.springframework.lang.NonNullApi;
* @author Chris Beams
* @since 3.1
*/
@NonNullApi
public interface ImportAware extends Aware {
/**

View File

@@ -19,7 +19,6 @@ package org.springframework.context.annotation;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
/**
* Interface to be implemented by types that register additional bean definitions when
@@ -48,7 +47,6 @@ import org.springframework.lang.NonNullApi;
* @see ImportSelector
* @see Configuration
*/
@NonNullApi
public interface ImportBeanDefinitionRegistrar {
/**

View File

@@ -17,15 +17,15 @@
package org.springframework.context.annotation;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
/**
* @author Juergen Hoeller
* @author Phil Webb
*/
@NonNullApi
interface ImportRegistry {
@Nullable
AnnotationMetadata getImportingClassFor(String importedClass);
void removeImportingClass(String importingClass);

View File

@@ -17,7 +17,6 @@
package org.springframework.context.annotation;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.NonNullApi;
/**
* Interface to be implemented by types that determine which @{@link Configuration}
@@ -46,7 +45,6 @@ import org.springframework.lang.NonNullApi;
* @see ImportBeanDefinitionRegistrar
* @see Configuration
*/
@NonNullApi
public interface ImportSelector {
/**

View File

@@ -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,7 +22,7 @@ import java.util.Set;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
/**
* Simple {@link ScopeMetadataResolver} implementation that follows JSR-330 scoping rules:
@@ -40,7 +40,6 @@ import org.springframework.lang.NonNullApi;
* @see ClassPathBeanDefinitionScanner#setScopeMetadataResolver
* @see AnnotatedBeanDefinitionReader#setScopeMetadataResolver
*/
@NonNullApi
public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver {
private final Map<String, String> scopeMap = new HashMap<>();
@@ -78,6 +77,7 @@ public class Jsr330ScopeMetadataResolver implements ScopeMetadataResolver {
* @param annotationType the JSR-330 annotation type
* @return the Spring scope name
*/
@Nullable
protected String resolveScopeName(String annotationType) {
return this.scopeMap.get(annotationType);
}

View File

@@ -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,7 +26,6 @@ import org.springframework.context.weaving.DefaultContextLoadTimeWeaver;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
/**
@@ -42,7 +41,6 @@ import org.springframework.lang.Nullable;
* @see ConfigurableApplicationContext#LOAD_TIME_WEAVER_BEAN_NAME
*/
@Configuration
@NonNullApi
public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoaderAware {
private AnnotationAttributes enableLTW;

View File

@@ -17,7 +17,6 @@
package org.springframework.context.annotation;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.lang.NonNullApi;
/**
* Interface to be implemented by
@@ -34,7 +33,6 @@ import org.springframework.lang.NonNullApi;
* @see LoadTimeWeavingConfiguration
* @see EnableLoadTimeWeaving
*/
@NonNullApi
public interface LoadTimeWeavingConfigurer {
/**

View File

@@ -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.
@@ -32,7 +32,6 @@ import org.springframework.jmx.export.annotation.AnnotationMBeanExporter;
import org.springframework.jmx.support.RegistrationPolicy;
import org.springframework.jmx.support.WebSphereMBeanServerFactoryBean;
import org.springframework.jndi.JndiLocatorDelegate;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -49,7 +48,6 @@ import org.springframework.util.StringUtils;
* @see EnableMBeanExport
*/
@Configuration
@NonNullApi
public class MBeanExportConfiguration implements ImportAware, EnvironmentAware, BeanFactoryAware {
private static final String MBEAN_EXPORTER_BEAN_NAME = "mbeanExporter";
@@ -94,7 +92,7 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
private void setupDomain(AnnotationMBeanExporter exporter) {
String defaultDomain = this.enableMBeanExport.getString("defaultDomain");
if (defaultDomain != null && this.environment != null) {
if (StringUtils.hasLength(defaultDomain) && this.environment != null) {
defaultDomain = this.environment.resolvePlaceholders(defaultDomain);
}
if (StringUtils.hasText(defaultDomain)) {
@@ -104,7 +102,7 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
private void setupServer(AnnotationMBeanExporter exporter) {
String server = this.enableMBeanExport.getString("server");
if (server != null && this.environment != null) {
if (StringUtils.hasLength(server) && this.environment != null) {
server = this.environment.resolvePlaceholders(server);
}
if (StringUtils.hasText(server)) {
@@ -113,7 +111,10 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
else {
SpecificPlatform specificPlatform = SpecificPlatform.get();
if (specificPlatform != null) {
exporter.setServer(specificPlatform.getMBeanServer());
MBeanServer mbeanServer = specificPlatform.getMBeanServer();
if (mbeanServer != null) {
exporter.setServer(mbeanServer);
}
}
}
}
@@ -124,7 +125,7 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
}
public static enum SpecificPlatform {
public enum SpecificPlatform {
WEBLOGIC("weblogic.management.Helper") {
@Override
@@ -149,10 +150,11 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
private final String identifyingClass;
private SpecificPlatform(String identifyingClass) {
SpecificPlatform(String identifyingClass) {
this.identifyingClass = identifyingClass;
}
@Nullable
public abstract MBeanServer getMBeanServer();
@Nullable

View File

@@ -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,7 +26,6 @@ import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.lang.NonNullApi;
/**
* Common delegate code for the handling of parser strategies, e.g.
@@ -35,7 +34,6 @@ import org.springframework.lang.NonNullApi;
* @author Juergen Hoeller
* @since 4.3.3
*/
@NonNullApi
abstract class ParserStrategyUtils {
/**
@@ -50,7 +48,9 @@ abstract class ParserStrategyUtils {
if (parserStrategyBean instanceof BeanClassLoaderAware) {
ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ?
((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader());
((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader);
if (classLoader != null) {
((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader);
}
}
if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) {
((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry);

View File

@@ -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.
@@ -32,16 +32,14 @@ class ProfileCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (context.getEnvironment() != null) {
MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
if (attrs != null) {
for (Object value : attrs.get("value")) {
if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
return true;
}
MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
if (attrs != null) {
for (Object value : attrs.get("value")) {
if (context.getEnvironment().acceptsProfiles((String[]) value)) {
return true;
}
return false;
}
return false;
}
return true;
}

View File

@@ -22,7 +22,6 @@ import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.lang.NonNullApi;
import org.springframework.util.Assert;
/**
@@ -46,7 +45,6 @@ import org.springframework.util.Assert;
* @see AnnotatedGenericBeanDefinition
*/
@SuppressWarnings("serial")
@NonNullApi
public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
private final AnnotationMetadata metadata;

View File

@@ -17,7 +17,6 @@
package org.springframework.context.annotation;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.lang.NonNullApi;
import org.springframework.util.Assert;
/**
@@ -33,7 +32,6 @@ import org.springframework.util.Assert;
* @see ScopeMetadataResolver
* @see ScopedProxyMode
*/
@NonNullApi
public class ScopeMetadata {
private String scopeName = BeanDefinition.SCOPE_SINGLETON;

View File

@@ -17,7 +17,6 @@
package org.springframework.context.annotation;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.lang.NonNullApi;
/**
* Strategy interface for resolving the scope of bean definitions.
@@ -27,7 +26,6 @@ import org.springframework.lang.NonNullApi;
* @see org.springframework.context.annotation.Scope
*/
@FunctionalInterface
@NonNullApi
public interface ScopeMetadataResolver {
/**

View File

@@ -19,7 +19,6 @@ package org.springframework.context.annotation;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.lang.NonNullApi;
/**
* Delegate factory class used to just introduce an AOP framework dependency
@@ -29,7 +28,6 @@ import org.springframework.lang.NonNullApi;
* @since 3.0
* @see org.springframework.aop.scope.ScopedProxyUtils#createScopedProxy
*/
@NonNullApi
class ScopedProxyCreator {
public static BeanDefinitionHolder createScopedProxy(

View File

@@ -3,4 +3,7 @@
* annotations, component-scanning, and Java-based metadata for creating
* Spring-managed objects.
*/
@NonNullApi
package org.springframework.context.annotation;
import org.springframework.lang.NonNullApi;

View File

@@ -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.
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.weaving.AspectJWeavingEnabler;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -94,12 +95,12 @@ class LoadTimeWeaverBeanDefinitionParser extends AbstractSingleBeanDefinitionPar
}
else {
// Determine default...
ClassLoader cl = parserContext.getReaderContext().getResourceLoader().getClassLoader();
return (cl.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) != null);
ClassLoader cl = parserContext.getReaderContext().getBeanClassLoader();
return (cl != null && cl.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) != null);
}
}
protected boolean isBeanConfigurerAspectEnabled(ClassLoader beanClassLoader) {
protected boolean isBeanConfigurerAspectEnabled(@Nullable ClassLoader beanClassLoader) {
return ClassUtils.isPresent(SpringConfiguredBeanDefinitionParser.BEAN_CONFIGURER_ASPECT_CLASS_NAME,
beanClassLoader);
}

View File

@@ -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.
@@ -61,7 +61,7 @@ class MBeanExportBeanDefinitionParser extends AbstractBeanDefinitionParser {
}
@Override
protected AbstractBeanDefinition parseInternal(@Nullable Element element, @Nullable ParserContext parserContext) {
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(AnnotationMBeanExporter.class);
// Mark as infrastructure bean and attach source location.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2008 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.
@@ -63,7 +63,7 @@ class MBeanServerBeanDefinitionParser extends AbstractBeanDefinitionParser {
}
@Override
protected AbstractBeanDefinition parseInternal(@Nullable Element element, @Nullable ParserContext parserContext) {
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
String agentId = element.getAttribute(AGENT_ID_ATTRIBUTE);
if (StringUtils.hasText(agentId)) {
RootBeanDefinition bd = new RootBeanDefinition(MBeanServerFactoryBean.class);

View File

@@ -34,6 +34,7 @@ import org.springframework.context.ApplicationListener;
import org.springframework.core.ResolvableType;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
@@ -72,7 +73,7 @@ public abstract class AbstractApplicationEventMulticaster
@Override
public void setBeanClassLoader(@Nullable ClassLoader classLoader) {
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@@ -208,7 +209,7 @@ public abstract class AbstractApplicationEventMulticaster
* @return the pre-filtered list of application listeners for the given event and source type
*/
private Collection<ApplicationListener<?>> retrieveApplicationListeners(
ResolvableType eventType, Class<?> sourceType, @Nullable ListenerRetriever retriever) {
ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable ListenerRetriever retriever) {
LinkedList<ApplicationListener<?>> allListeners = new LinkedList<>();
Set<ApplicationListener<?>> listeners;
@@ -283,7 +284,9 @@ public abstract class AbstractApplicationEventMulticaster
* @return whether the given listener should be included in the candidates
* for the given event type
*/
protected boolean supportsEvent(ApplicationListener<?> listener, ResolvableType eventType, Class<?> sourceType) {
protected boolean supportsEvent(
ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) {
GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ?
(GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener));
return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType));
@@ -299,7 +302,8 @@ public abstract class AbstractApplicationEventMulticaster
private final Class<?> sourceType;
public ListenerCacheKey(ResolvableType eventType, Class<?> sourceType) {
public ListenerCacheKey(ResolvableType eventType, @Nullable Class<?> sourceType) {
Assert.notNull(eventType, "Event type must not be null");
this.eventType = eventType;
this.sourceType = sourceType;
}
@@ -310,27 +314,30 @@ public abstract class AbstractApplicationEventMulticaster
return true;
}
ListenerCacheKey otherKey = (ListenerCacheKey) other;
return (ObjectUtils.nullSafeEquals(this.eventType, otherKey.eventType) &&
return (this.eventType.equals(otherKey.eventType) &&
ObjectUtils.nullSafeEquals(this.sourceType, otherKey.sourceType));
}
@Override
public int hashCode() {
return (ObjectUtils.nullSafeHashCode(this.eventType) * 29 + ObjectUtils.nullSafeHashCode(this.sourceType));
return this.eventType.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.sourceType);
}
@Override
public String toString() {
return "ListenerCacheKey [eventType = " + this.eventType + ", sourceType = " + this.sourceType.getName() + "]";
return "ListenerCacheKey [eventType = " + this.eventType + ", sourceType = " + this.sourceType + "]";
}
@Override
public int compareTo(ListenerCacheKey other) {
int result = 0;
if (this.eventType != null) {
result = this.eventType.toString().compareTo(other.eventType.toString());
}
if (result == 0 && this.sourceType != null) {
int result = this.eventType.toString().compareTo(other.eventType.toString());
if (result == 0) {
if (this.sourceType == null) {
return (other.sourceType == null ? 0 : -1);
}
if (other.sourceType == null) {
return 1;
}
result = this.sourceType.getName().compareTo(other.sourceType.getName());
}
return result;

View File

@@ -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.
@@ -97,7 +97,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
}
private List<ResolvableType> resolveDeclaredEventTypes(Method method, EventListener ann) {
private List<ResolvableType> resolveDeclaredEventTypes(Method method, @Nullable EventListener ann) {
int count = method.getParameterCount();
if (count > 1) {
throw new IllegalStateException(
@@ -144,7 +144,8 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
if (declaredEventType.isAssignableFrom(eventType)) {
return true;
}
else if (PayloadApplicationEvent.class.isAssignableFrom(eventType.getRawClass())) {
Class<?> eventClass = eventType.getRawClass();
if (eventClass != null && PayloadApplicationEvent.class.isAssignableFrom(eventClass)) {
ResolvableType payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric();
if (declaredEventType.isAssignableFrom(payloadType)) {
return true;
@@ -155,7 +156,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
}
@Override
public boolean supportsSourceType(Class<?> sourceType) {
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return true;
}
@@ -197,7 +198,8 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
if (this.method.getParameterCount() == 0) {
return new Object[0];
}
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass()) &&
Class<?> eventClass = declaredEventType.getRawClass();
if ((eventClass == null || !ApplicationEvent.class.isAssignableFrom(eventClass)) &&
event instanceof PayloadApplicationEvent) {
return new Object[] {((PayloadApplicationEvent) event).getPayload()};
}
@@ -224,14 +226,14 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
}
}
private void publishEvent(Object event) {
private void publishEvent(@Nullable Object event) {
if (event != null) {
Assert.notNull(this.applicationContext, "ApplicationContext must no be null");
Assert.notNull(this.applicationContext, "ApplicationContext must not be null");
this.applicationContext.publishEvent(event);
}
}
private boolean shouldHandle(ApplicationEvent event, Object[] args) {
private boolean shouldHandle(ApplicationEvent event, @Nullable Object[] args) {
if (args == null) {
return false;
}
@@ -248,6 +250,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
/**
* Invoke the event listener method with the given argument values.
*/
@Nullable
protected Object doInvoke(Object... args) {
Object bean = getTargetBean();
ReflectionUtils.makeAccessible(this.bridgedMethod);
@@ -345,10 +348,14 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
ResolvableType payloadType = null;
if (event instanceof PayloadApplicationEvent) {
PayloadApplicationEvent<?> payloadEvent = (PayloadApplicationEvent<?>) event;
payloadType = payloadEvent.getResolvableType().as(PayloadApplicationEvent.class).getGeneric();
ResolvableType eventType = payloadEvent.getResolvableType();
if (eventType != null) {
payloadType = eventType.as(PayloadApplicationEvent.class).getGeneric();
}
}
for (ResolvableType declaredEventType : this.declaredEventTypes) {
if (!ApplicationEvent.class.isAssignableFrom(declaredEventType.getRawClass()) && payloadType != null) {
Class<?> eventClass = declaredEventType.getRawClass();
if ((eventClass == null || !ApplicationEvent.class.isAssignableFrom(eventClass)) && payloadType != null) {
if (declaredEventType.isAssignableFrom(payloadType)) {
return declaredEventType;
}

View File

@@ -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.context.expression.CachedExpressionEvaluator;
import org.springframework.context.expression.MethodBasedEvaluationContext;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.lang.Nullable;
/**
* Utility class handling the SpEL expression parsing. Meant to be used
@@ -50,7 +51,7 @@ class EventExpressionEvaluator extends CachedExpressionEvaluator {
* on the specified method.
*/
public EvaluationContext createEvaluationContext(ApplicationEvent event, Class<?> targetClass,
Method method, Object[] args, BeanFactory beanFactory) {
Method method, Object[] args, @Nullable BeanFactory beanFactory) {
Method targetMethod = getTargetMethod(targetClass, method);
EventExpressionRootObject root = new EventExpressionRootObject(event, args);
@@ -65,11 +66,9 @@ class EventExpressionEvaluator extends CachedExpressionEvaluator {
/**
* Specify if the condition defined by the specified expression matches.
*/
public boolean condition(String conditionExpression,
AnnotatedElementKey elementKey, EvaluationContext evalContext) {
return getExpression(this.conditionCache, elementKey, conditionExpression)
.getValue(evalContext, boolean.class);
public boolean condition(String conditionExpression, AnnotatedElementKey elementKey, EvaluationContext evalContext) {
return (Boolean.TRUE.equals(getExpression(this.conditionCache, elementKey, conditionExpression).getValue(
evalContext, Boolean.class)));
}
private Method getTargetMethod(Class<?> targetClass, Method method) {
@@ -77,9 +76,6 @@ class EventExpressionEvaluator extends CachedExpressionEvaluator {
Method targetMethod = this.targetMethodCache.get(methodKey);
if (targetMethod == null) {
targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
if (targetMethod == null) {
targetMethod = method;
}
this.targetMethodCache.put(methodKey, targetMethod);
}
return targetMethod;

View File

@@ -89,8 +89,12 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
if (type != null) {
if (ScopedObject.class.isAssignableFrom(type)) {
try {
type = AutoProxyUtils.determineTargetClass(this.applicationContext.getBeanFactory(),
Class<?> targetClass = AutoProxyUtils.determineTargetClass(
this.applicationContext.getBeanFactory(),
ScopedProxyUtils.getTargetBeanName(beanName));
if (targetClass != null) {
type = targetClass;
}
}
catch (Throwable ex) {
// An invalid scoped proxy arrangement - let's ignore it.
@@ -123,16 +127,15 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
return allFactories;
}
protected void processBean(final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
protected void processBean(
final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
if (!this.nonAnnotatedClasses.contains(targetType)) {
Map<Method, EventListener> annotatedMethods = null;
try {
annotatedMethods = MethodIntrospector.selectMethods(targetType,
new MethodIntrospector.MetadataLookup<EventListener>() {
@Override
public EventListener inspect(Method method) {
return AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);
}
(MethodIntrospector.MetadataLookup<EventListener>) method -> {
return AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class);
});
}
catch (Throwable ex) {

View File

@@ -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.
@@ -20,6 +20,7 @@ import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
/**
* Extended variant of the standard {@link ApplicationListener} interface,
@@ -41,6 +42,6 @@ public interface GenericApplicationListener extends ApplicationListener<Applicat
/**
* Determine whether this listener actually supports the given source type.
*/
boolean supportsSourceType(Class<?> sourceType);
boolean supportsSourceType(@Nullable Class<?> sourceType);
}

View File

@@ -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.
@@ -75,13 +75,9 @@ public class GenericApplicationListenerAdapter implements GenericApplicationList
}
@Override
public boolean supportsSourceType(Class<?> sourceType) {
if (this.delegate instanceof SmartApplicationListener) {
return ((SmartApplicationListener) this.delegate).supportsSourceType(sourceType);
}
else {
return true;
}
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return !(this.delegate instanceof SmartApplicationListener) ||
((SmartApplicationListener) this.delegate).supportsSourceType(sourceType);
}
@Override
@@ -92,12 +88,10 @@ public class GenericApplicationListenerAdapter implements GenericApplicationList
@Nullable
static ResolvableType resolveDeclaredEventType(Class<?> listenerType) {
ResolvableType resolvableType = ResolvableType.forClass(listenerType).as(ApplicationListener.class);
if (resolvableType == null || !resolvableType.hasGenerics()) {
return null;
}
return resolvableType.getGeneric();
return (resolvableType.hasGenerics() ? resolvableType.getGeneric() : null);
}
@Nullable
private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) {
ResolvableType declaredEventType = resolveDeclaredEventType(listener.getClass());
if (declaredEventType == null || declaredEventType.isAssignableFrom(

View File

@@ -79,13 +79,14 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
* @see org.springframework.core.task.SyncTaskExecutor
* @see org.springframework.core.task.SimpleAsyncTaskExecutor
*/
public void setTaskExecutor(Executor taskExecutor) {
public void setTaskExecutor(@Nullable Executor taskExecutor) {
this.taskExecutor = taskExecutor;
}
/**
* Return the current task executor for this multicaster.
*/
@Nullable
protected Executor getTaskExecutor() {
return this.taskExecutor;
}
@@ -105,7 +106,7 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
* (e.g. {@link org.springframework.scheduling.support.TaskUtils#LOG_AND_PROPAGATE_ERROR_HANDLER}).
* @since 4.1
*/
public void setErrorHandler(ErrorHandler errorHandler) {
public void setErrorHandler(@Nullable ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
@@ -113,6 +114,7 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
* Return the current error handler for this multicaster.
* @since 4.1
*/
@Nullable
protected ErrorHandler getErrorHandler() {
return this.errorHandler;
}
@@ -129,12 +131,7 @@ public class SimpleApplicationEventMulticaster extends AbstractApplicationEventM
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
executor.execute(() -> invokeListener(listener, event));
}
else {
invokeListener(listener, event);

View File

@@ -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.
@@ -19,6 +19,7 @@ package org.springframework.context.event;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.lang.Nullable;
/**
* Extended variant of the standard {@link ApplicationListener} interface,
@@ -42,6 +43,6 @@ public interface SmartApplicationListener extends ApplicationListener<Applicatio
/**
* Determine whether this listener actually supports the given source type.
*/
boolean supportsSourceType(Class<?> sourceType);
boolean supportsSourceType(@Nullable Class<?> sourceType);
}

View File

@@ -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.
@@ -20,6 +20,7 @@ import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
/**
* {@link org.springframework.context.ApplicationListener} decorator that filters
@@ -83,7 +84,7 @@ public class SourceFilteringListener implements GenericApplicationListener, Smar
}
@Override
public boolean supportsSourceType(Class<?> sourceType) {
public boolean supportsSourceType(@Nullable Class<?> sourceType) {
return (sourceType != null && sourceType.isInstance(this.source));
}

View File

@@ -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.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* EL property accessor that knows how to traverse the beans and contextual objects
@@ -33,22 +35,25 @@ import org.springframework.expression.TypedValue;
public class BeanExpressionContextAccessor implements PropertyAccessor {
@Override
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
return ((BeanExpressionContext) target).containsObject(name);
public boolean canRead(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
return (target instanceof BeanExpressionContext && ((BeanExpressionContext) target).containsObject(name));
}
@Override
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
public TypedValue read(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
Assert.state(target instanceof BeanExpressionContext, "Target must be of type BeanExpressionContext");
return new TypedValue(((BeanExpressionContext) target).getObject(name));
}
@Override
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
public boolean canWrite(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
return false;
}
@Override
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
public void write(EvaluationContext context, @Nullable Object target, String name, @Nullable Object newValue)
throws AccessException {
throw new AccessException("Beans in a BeanFactory are read-only");
}

View File

@@ -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 org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* EL property accessor that knows how to traverse the beans of a
@@ -38,22 +40,25 @@ public class BeanFactoryAccessor implements PropertyAccessor {
}
@Override
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
return (((BeanFactory) target).containsBean(name));
public boolean canRead(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
return (target instanceof BeanFactory && ((BeanFactory) target).containsBean(name));
}
@Override
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
public TypedValue read(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
Assert.state(target instanceof BeanFactory, "Target must be of type BeanFactory");
return new TypedValue(((BeanFactory) target).getBean(name));
}
@Override
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
public boolean canWrite(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
return false;
}
@Override
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
public void write(EvaluationContext context, @Nullable Object target, String name, @Nullable Object newValue)
throws AccessException {
throw new AccessException("Beans in a BeanFactory are read-only");
}

View File

@@ -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.
@@ -103,6 +103,8 @@ public abstract class CachedExpressionEvaluator {
private final String expression;
protected ExpressionKey(AnnotatedElementKey element, String expression) {
Assert.notNull(element, "AnnotatedElementKey must not be null");
Assert.notNull(expression, "Expression must not be null");
this.element = element;
this.expression = expression;
}
@@ -122,12 +124,12 @@ public abstract class CachedExpressionEvaluator {
@Override
public int hashCode() {
return this.element.hashCode() + (this.expression != null ? this.expression.hashCode() * 29 : 0);
return this.element.hashCode() * 29 + this.expression.hashCode();
}
@Override
public String toString() {
return this.element + (this.expression != null ? " with expression \"" + this.expression : "\"");
return this.element + " with expression \"" + this.expression + "\"";
}
@Override

View File

@@ -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.
@@ -21,6 +21,8 @@ import org.springframework.expression.AccessException;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.PropertyAccessor;
import org.springframework.expression.TypedValue;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Read-only EL property accessor that knows how to retrieve keys
@@ -41,7 +43,7 @@ public class EnvironmentAccessor implements PropertyAccessor {
* @return true
*/
@Override
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
public boolean canRead(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
return true;
}
@@ -50,7 +52,8 @@ public class EnvironmentAccessor implements PropertyAccessor {
* environment.
*/
@Override
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
public TypedValue read(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
Assert.state(target instanceof Environment, "Target must be of type Environment");
return new TypedValue(((Environment) target).getProperty(name));
}
@@ -58,7 +61,7 @@ public class EnvironmentAccessor implements PropertyAccessor {
* Read-only: returns {@code false}.
*/
@Override
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
public boolean canWrite(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
return false;
}
@@ -66,7 +69,8 @@ public class EnvironmentAccessor implements PropertyAccessor {
* Read-only: no-op.
*/
@Override
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
public void write(EvaluationContext context, @Nullable Object target, String name, @Nullable Object newValue)
throws AccessException {
}
}

View File

@@ -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.
@@ -24,6 +24,8 @@ import org.springframework.expression.EvaluationContext;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.CodeFlow;
import org.springframework.expression.spel.CompilablePropertyAccessor;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* EL property accessor that knows how to traverse the keys
@@ -41,13 +43,13 @@ public class MapAccessor implements CompilablePropertyAccessor {
}
@Override
public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
Map<?, ?> map = (Map<?, ?>) target;
return map.containsKey(name);
public boolean canRead(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
return (target instanceof Map && ((Map<?, ?>) target).containsKey(name));
}
@Override
public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
public TypedValue read(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
Assert.state(target instanceof Map, "Target must be of type Map");
Map<?, ?> map = (Map<?, ?>) target;
Object value = map.get(name);
if (value == null && !map.containsKey(name)) {
@@ -57,38 +59,20 @@ public class MapAccessor implements CompilablePropertyAccessor {
}
@Override
public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
public boolean canWrite(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
return true;
}
@Override
@SuppressWarnings("unchecked")
public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
public void write(EvaluationContext context, @Nullable Object target, String name, @Nullable Object newValue)
throws AccessException {
Assert.state(target instanceof Map, "Target must be a Map");
Map<Object, Object> map = (Map<Object, Object>) target;
map.put(name, newValue);
}
/**
* Exception thrown from {@code read} in order to reset a cached
* PropertyAccessor, allowing other accessors to have a try.
*/
@SuppressWarnings("serial")
private static class MapAccessException extends AccessException {
private final String key;
public MapAccessException(String key) {
super(null);
this.key = key;
}
@Override
public String getMessage() {
return "Map does not contain a value for key '" + this.key + "'";
}
}
@Override
public boolean isCompilable() {
return true;
@@ -112,4 +96,25 @@ public class MapAccessor implements CompilablePropertyAccessor {
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get","(Ljava/lang/Object;)Ljava/lang/Object;",true);
}
/**
* Exception thrown from {@code read} in order to reset a cached
* PropertyAccessor, allowing other accessors to have a try.
*/
@SuppressWarnings("serial")
private static class MapAccessException extends AccessException {
private final String key;
public MapAccessException(String key) {
super("");
this.key = key;
}
@Override
public String getMessage() {
return "Map does not contain a value for key '" + this.key + "'";
}
}
}

View File

@@ -32,6 +32,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.expression.spel.support.StandardTypeConverter;
import org.springframework.expression.spel.support.StandardTypeLocator;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -131,7 +132,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
@Override
public Object evaluate(String value, BeanExpressionContext evalContext) throws BeansException {
public Object evaluate(@Nullable String value, BeanExpressionContext evalContext) throws BeansException {
if (!StringUtils.hasLength(value)) {
return value;
}
@@ -160,7 +161,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
}
return expr.getValue(sec);
}
catch (Exception ex) {
catch (Throwable ex) {
throw new BeanExpressionException("Expression parsing failed", ex);
}
}

View File

@@ -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,8 @@ package org.springframework.context.i18n;
import java.util.Locale;
import org.springframework.lang.Nullable;
/**
* Simple implementation of the {@link LocaleContext} interface,
* always returning a specified {@code Locale}.
@@ -36,9 +38,9 @@ public class SimpleLocaleContext implements LocaleContext {
/**
* Create a new SimpleLocaleContext that exposes the specified Locale.
* Every {@link #getLocale()} call will return this Locale.
* @param locale the Locale to expose
* @param locale the Locale to expose, or {@code null} for no specific one
*/
public SimpleLocaleContext(Locale locale) {
public SimpleLocaleContext(@Nullable Locale locale) {
this.locale = locale;
}

View File

@@ -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.
@@ -19,6 +19,8 @@ package org.springframework.context.i18n;
import java.util.Locale;
import java.util.TimeZone;
import org.springframework.lang.Nullable;
/**
* Simple implementation of the {@link TimeZoneAwareLocaleContext} interface,
* always returning a specified {@code Locale} and {@code TimeZone}.
@@ -44,7 +46,7 @@ public class SimpleTimeZoneAwareLocaleContext extends SimpleLocaleContext implem
* @param locale the Locale to expose
* @param timeZone the TimeZone to expose
*/
public SimpleTimeZoneAwareLocaleContext(Locale locale, TimeZone timeZone) {
public SimpleTimeZoneAwareLocaleContext(@Nullable Locale locale, @Nullable TimeZone timeZone) {
super(locale);
this.timeZone = timeZone;
}

View File

@@ -221,7 +221,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* Create a new AbstractApplicationContext with the given parent context.
* @param parent the parent context
*/
public AbstractApplicationContext(ApplicationContext parent) {
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
this();
setParent(parent);
}
@@ -843,12 +843,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(@Nullable String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
@@ -1087,18 +1082,18 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
return getBeanFactory().getBean(name, requiredType);
}
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(name, args);
}
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
@Override
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
assertBeanFactoryActive();
@@ -1129,7 +1124,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
@Override
public boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
public boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
assertBeanFactoryActive();
return getBeanFactory().isTypeMatch(name, typeToMatch);
}
@@ -1166,7 +1161,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
}
@Override
public String[] getBeanNamesForType(@Nullable ResolvableType type) {
public String[] getBeanNamesForType(ResolvableType type) {
assertBeanFactoryActive();
return getBeanFactory().getBeanNamesForType(type);
}
@@ -1239,6 +1234,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* ConfigurableApplicationContext; else, return the parent context itself.
* @see org.springframework.context.ConfigurableApplicationContext#getBeanFactory
*/
@Nullable
protected BeanFactory getInternalParentBeanFactory() {
return (getParent() instanceof ConfigurableApplicationContext) ?
((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
@@ -1281,6 +1277,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* Return the internal message source of the parent context if it is an
* AbstractApplicationContext too; else, return the parent context itself.
*/
@Nullable
protected MessageSource getInternalParentMessageSource() {
return (getParent() instanceof AbstractApplicationContext) ?
((AbstractApplicationContext) getParent()).messageSource : getParent();

View File

@@ -141,9 +141,7 @@ public abstract class AbstractMessageSource extends MessageSourceSupport impleme
}
if (defaultMessage == null) {
String fallback = getDefaultMessage(code);
if (fallback != null) {
return fallback;
}
return (fallback != null ? fallback : "");
}
return renderDefaultMessage(defaultMessage, args, locale);
}
@@ -176,7 +174,7 @@ public abstract class AbstractMessageSource extends MessageSourceSupport impleme
if (defaultMessage != null) {
return defaultMessage;
}
throw new NoSuchMessageException(!ObjectUtils.isEmpty(codes) ? codes[codes.length - 1] : null, locale);
throw new NoSuchMessageException(!ObjectUtils.isEmpty(codes) ? codes[codes.length - 1] : "", locale);
}
@@ -195,7 +193,7 @@ public abstract class AbstractMessageSource extends MessageSourceSupport impleme
* @see #setUseCodeAsDefaultMessage
*/
@Nullable
protected String getMessageInternal(String code, Object[] args, Locale locale) {
protected String getMessageInternal(@Nullable String code, @Nullable Object[] args, @Nullable Locale locale) {
if (code == null) {
return null;
}
@@ -252,7 +250,7 @@ public abstract class AbstractMessageSource extends MessageSourceSupport impleme
* @see #getParentMessageSource()
*/
@Nullable
protected String getMessageFromParent(String code, Object[] args, Locale locale) {
protected String getMessageFromParent(String code, @Nullable Object[] args, Locale locale) {
MessageSource parent = getParentMessageSource();
if (parent != null) {
if (parent instanceof AbstractMessageSource) {
@@ -323,9 +321,9 @@ public abstract class AbstractMessageSource extends MessageSourceSupport impleme
* @return an array of arguments with any MessageSourceResolvables resolved
*/
@Override
protected Object[] resolveArguments(Object[] args, Locale locale) {
if (args == null) {
return new Object[0];
protected Object[] resolveArguments(@Nullable Object[] args, Locale locale) {
if (ObjectUtils.isEmpty(args)) {
return super.resolveArguments(args, locale);
}
List<Object> resolvedArgs = new ArrayList<>(args.length);
for (Object arg : args) {

View File

@@ -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.
@@ -23,6 +23,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextException;
import org.springframework.lang.Nullable;
/**
* Base class for {@link org.springframework.context.ApplicationContext}
@@ -84,7 +85,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
* Create a new AbstractRefreshableApplicationContext with the given parent context.
* @param parent the parent context
*/
public AbstractRefreshableApplicationContext(ApplicationContext parent) {
public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) {
super(parent);
}

View File

@@ -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.
@@ -54,7 +54,7 @@ public abstract class AbstractRefreshableConfigApplicationContext extends Abstra
* Create a new AbstractRefreshableConfigApplicationContext with the given parent context.
* @param parent the parent context
*/
public AbstractRefreshableConfigApplicationContext(ApplicationContext parent) {
public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) {
super(parent);
}
@@ -72,7 +72,7 @@ public abstract class AbstractRefreshableConfigApplicationContext extends Abstra
* Set the config locations for this application context.
* <p>If not set, the implementation may use a default as appropriate.
*/
public void setConfigLocations(String... locations) {
public void setConfigLocations(@Nullable String... locations) {
if (locations != null) {
Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];

View File

@@ -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.
@@ -58,7 +58,7 @@ public abstract class AbstractXmlApplicationContext extends AbstractRefreshableC
* Create a new AbstractXmlApplicationContext with the given parent context.
* @param parent the parent context
*/
public AbstractXmlApplicationContext(ApplicationContext parent) {
public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) {
super(parent);
}

View File

@@ -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.
@@ -85,12 +85,9 @@ class ApplicationContextAwareProcessor implements BeanPostProcessor {
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {

View File

@@ -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 org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationContextException;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Convenient superclass for application objects that want to be aware of
@@ -57,7 +59,7 @@ public abstract class ApplicationObjectSupport implements ApplicationContextAwar
@Override
public final void setApplicationContext(ApplicationContext context) throws BeansException {
public final void setApplicationContext(@Nullable ApplicationContext context) throws BeansException {
if (context == null && !isContextRequired()) {
// Reset internal context state.
this.applicationContext = null;
@@ -136,6 +138,7 @@ public abstract class ApplicationObjectSupport implements ApplicationContextAwar
* Return the ApplicationContext that this object is associated with.
* @throws IllegalStateException if not running in an ApplicationContext
*/
@Nullable
public final ApplicationContext getApplicationContext() throws IllegalStateException {
if (this.applicationContext == null && isContextRequired()) {
throw new IllegalStateException(
@@ -144,11 +147,24 @@ public abstract class ApplicationObjectSupport implements ApplicationContextAwar
return this.applicationContext;
}
/**
* Obtain the ApplicationContext for actual use.
* @return the ApplicationContext (never {@code null})
* @throws IllegalStateException in case of no ApplicationContext set
* @since 5.0
*/
protected final ApplicationContext obtainApplicationContext() {
ApplicationContext applicationContext = getApplicationContext();
Assert.state(applicationContext != null, "No ApplicationContext");
return applicationContext;
}
/**
* Return a MessageSourceAccessor for the application context
* used by this object, for easy message access.
* @throws IllegalStateException if not running in an ApplicationContext
*/
@Nullable
protected final MessageSourceAccessor getMessageSourceAccessor() throws IllegalStateException {
if (this.messageSourceAccessor == null && isContextRequired()) {
throw new IllegalStateException(

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 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.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -101,7 +102,9 @@ public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContex
* @param parent the parent context
* @throws BeansException if context creation failed
*/
public ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {
public ClassPathXmlApplicationContext(String[] configLocations, @Nullable ApplicationContext parent)
throws BeansException {
this(configLocations, true, parent);
}
@@ -130,7 +133,8 @@ public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContex
* @throws BeansException if context creation failed
* @see #refresh()
*/
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
@@ -184,7 +188,7 @@ public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContex
* @see org.springframework.context.support.GenericApplicationContext
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
*/
public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, ApplicationContext parent)
public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);

View File

@@ -278,8 +278,8 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
boolean isFactoryBean = this.beanFactory.isFactoryBean(beanNameToRegister);
String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
if ((this.beanFactory.containsSingleton(beanNameToRegister) &&
(!isFactoryBean || Lifecycle.class.isAssignableFrom(this.beanFactory.getType(beanNameToCheck)))) ||
SmartLifecycle.class.isAssignableFrom(this.beanFactory.getType(beanNameToCheck))) {
(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck))) ||
matchesBeanType(SmartLifecycle.class, beanNameToCheck)) {
Lifecycle bean = this.beanFactory.getBean(beanNameToCheck, Lifecycle.class);
if (bean != this) {
beans.put(beanNameToRegister, bean);
@@ -289,6 +289,11 @@ public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactor
return beans;
}
private boolean matchesBeanType(Class<?> targetType, String beanName) {
Class<?> beanType = this.beanFactory.getType(beanName);
return (beanType != null && targetType.isAssignableFrom(beanType));
}
/**
* Determine the lifecycle phase of the given bean.
* <p>The default implementation checks for the {@link Phased} interface.

View File

@@ -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,7 @@ package org.springframework.context.support;
import java.io.Serializable;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -81,7 +82,9 @@ public class DefaultMessageSourceResolvable implements MessageSourceResolvable,
* @param arguments the array of arguments to be used to resolve this message
* @param defaultMessage the default message to be used to resolve this message
*/
public DefaultMessageSourceResolvable(String[] codes, Object[] arguments, String defaultMessage) {
public DefaultMessageSourceResolvable(
@Nullable String[] codes, @Nullable Object[] arguments, @Nullable String defaultMessage) {
this.codes = codes;
this.arguments = arguments;
this.defaultMessage = defaultMessage;
@@ -96,19 +99,20 @@ public class DefaultMessageSourceResolvable implements MessageSourceResolvable,
}
@Override
public String[] getCodes() {
return this.codes;
}
/**
* Return the default code of this resolvable, that is,
* the last one in the codes array.
*/
@Nullable
public String getCode() {
return (this.codes != null && this.codes.length > 0 ? this.codes[this.codes.length - 1] : null);
}
@Override
public String[] getCodes() {
return this.codes;
}
@Override
public Object[] getArguments() {
return this.arguments;

View File

@@ -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.
@@ -56,9 +56,12 @@ public class DelegatingMessageSource extends MessageSourceSupport implements Hie
if (this.parentMessageSource != null) {
return this.parentMessageSource.getMessage(code, args, defaultMessage, locale);
}
else {
else if (defaultMessage != null) {
return renderDefaultMessage(defaultMessage, args, locale);
}
else {
return "";
}
}
@Override
@@ -81,7 +84,7 @@ public class DelegatingMessageSource extends MessageSourceSupport implements Hie
return renderDefaultMessage(resolvable.getDefaultMessage(), resolvable.getArguments(), locale);
}
String[] codes = resolvable.getCodes();
String code = (codes != null && codes.length > 0 ? codes[0] : null);
String code = (codes != null && codes.length > 0 ? codes[0] : "");
throw new NoSuchMessageException(code, locale);
}
}

View File

@@ -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.context.support;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.lang.Nullable;
import org.springframework.util.StringValueResolver;
/**
@@ -42,6 +43,7 @@ public class EmbeddedValueResolutionSupport implements EmbeddedValueResolverAwar
* @return the resolved value, or always the original value if no resolver is available
* @see #setEmbeddedValueResolver
*/
@Nullable
protected String resolveEmbeddedValue(String value) {
return (this.embeddedValueResolver != null ? this.embeddedValueResolver.resolveStringValue(value) : value);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 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.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
/**
* Standalone XML application context, taking the context definition files
@@ -131,7 +132,8 @@ public class FileSystemXmlApplicationContext extends AbstractXmlApplicationConte
* @throws BeansException if context creation failed
* @see #refresh()
*/
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
public FileSystemXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
@@ -153,7 +155,7 @@ public class FileSystemXmlApplicationContext extends AbstractXmlApplicationConte
*/
@Override
protected Resource getResourceByPath(String path) {
if (path != null && path.startsWith("/")) {
if (path.startsWith("/")) {
path = path.substring(1);
}
return new FileSystemResource(path);

View File

@@ -126,7 +126,7 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext(ApplicationContext parent) {
public GenericApplicationContext(@Nullable ApplicationContext parent) {
this();
setParent(parent);
}
@@ -330,7 +330,7 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
}
@Override
public BeanDefinition getBeanDefinition(@Nullable String beanName) throws NoSuchBeanDefinitionException {
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
return this.beanFactory.getBeanDefinition(beanName);
}
@@ -419,13 +419,15 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
* factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag
* @since 5.0
*/
public <T> void registerBean(@Nullable String beanName, @Nullable Class<T> beanClass, @Nullable Supplier<T> supplier,
public <T> void registerBean(@Nullable String beanName, Class<T> beanClass, @Nullable Supplier<T> supplier,
BeanDefinitionCustomizer... customizers) {
Assert.isTrue(beanName != null || beanClass != null, "Either bean name or bean class must be specified");
BeanDefinitionBuilder builder = (supplier != null ?
BeanDefinitionBuilder.genericBeanDefinition(beanClass, supplier) :
BeanDefinitionBuilder.genericBeanDefinition(beanClass));
BeanDefinition beanDefinition = builder.applyCustomizers(customizers).getRawBeanDefinition();
String nameToUse = (beanName != null ? beanName : beanClass.getName());
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(beanClass, supplier).
applyCustomizers(customizers).getRawBeanDefinition();
registerBeanDefinition(nameToUse, beanDefinition);
}

View File

@@ -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.
@@ -28,6 +28,7 @@ import org.springframework.beans.factory.groovy.GroovyBeanDefinitionReader;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.lang.Nullable;
/**
* An {@link org.springframework.context.ApplicationContext} implementation that extends
@@ -245,6 +246,7 @@ public class GenericGroovyApplicationContext extends GenericApplicationContext i
}
}
@Nullable
public Object getProperty(String property) {
if (containsBean(property)) {
return getBean(property);

View File

@@ -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,7 +88,9 @@ public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAwar
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
String mbeanDomain = applicationContext.getEnvironment().getProperty(MBEAN_DOMAIN_PROPERTY_NAME);
server.unregisterMBean(new ObjectName(mbeanDomain, MBEAN_APPLICATION_KEY, applicationName));
if (mbeanDomain != null) {
server.unregisterMBean(new ObjectName(mbeanDomain, MBEAN_APPLICATION_KEY, applicationName));
}
}
catch (Throwable ex) {
throw new ApplicationContextException("Failed to unregister LiveBeansView MBean", ex);

Some files were not shown because too many files have changed in this diff Show More