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:
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <context:annotation-config/> element.
|
||||
@@ -37,7 +36,6 @@ import org.springframework.lang.NonNullApi;
|
||||
* @since 2.5
|
||||
* @see AnnotationConfigUtils
|
||||
*/
|
||||
@NonNullApi
|
||||
public class AnnotationConfigBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 [" +
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
/**
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 + "'";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user