@Nullable all the way: null-safety at field level

This commits extends nullability declarations to the field level, formalizing the interaction between methods and their underlying fields and therefore avoiding any nullability mismatch.

Issue: SPR-15720
This commit is contained in:
Juergen Hoeller
2017-06-30 01:53:45 +02:00
parent c4694c3f5c
commit cc74a2891a
936 changed files with 6090 additions and 2806 deletions

View File

@@ -169,6 +169,7 @@ public interface Cache {
@SuppressWarnings("serial")
class ValueRetrievalException extends RuntimeException {
@Nullable
private final Object key;
public ValueRetrievalException(@Nullable Object key, Callable<?> loader, Throwable ex) {

View File

@@ -27,6 +27,7 @@ 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;
/**
@@ -41,14 +42,19 @@ import org.springframework.util.CollectionUtils;
@Configuration
public abstract class AbstractCachingConfiguration implements ImportAware {
@Nullable
protected AnnotationAttributes enableCaching;
@Nullable
protected CacheManager cacheManager;
@Nullable
protected CacheResolver cacheResolver;
@Nullable
protected KeyGenerator keyGenerator;
@Nullable
protected CacheErrorHandler errorHandler;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,7 +44,9 @@ public class ProxyCachingConfiguration extends AbstractCachingConfiguration {
new BeanFactoryCacheOperationSourceAdvisor();
advisor.setCacheOperationSource(cacheOperationSource());
advisor.setAdvice(cacheInterceptor());
advisor.setOrder(this.enableCaching.<Integer>getNumber("order"));
if (this.enableCaching != null) {
advisor.setOrder(this.enableCaching.<Integer>getNumber("order"));
}
return advisor;
}

View File

@@ -263,12 +263,16 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
*/
static class DefaultCacheConfig {
@Nullable
private final String[] cacheNames;
@Nullable
private final String keyGenerator;
@Nullable
private final String cacheManager;
@Nullable
private final String cacheResolver;
public DefaultCacheConfig() {

View File

@@ -52,6 +52,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
private final ConcurrentMap<Object, Object> store;
@Nullable
private final SerializationDelegate serialization;
@@ -176,7 +177,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
Object storeValue = super.toStoreValue(userValue);
if (this.serialization != null) {
try {
return serializeValue(storeValue);
return serializeValue(this.serialization, storeValue);
}
catch (Throwable ex) {
throw new IllegalArgumentException("Failed to serialize cache value '" + userValue +
@@ -188,10 +189,10 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
}
}
private Object serializeValue(Object storeValue) throws IOException {
private Object serializeValue(SerializationDelegate serialization, Object storeValue) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
this.serialization.serialize(storeValue, out);
serialization.serialize(storeValue, out);
return out.toByteArray();
}
finally {
@@ -203,7 +204,7 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
protected Object fromStoreValue(Object storeValue) {
if (this.serialization != null) {
try {
return super.fromStoreValue(deserializeValue(storeValue));
return super.fromStoreValue(deserializeValue(this.serialization, storeValue));
}
catch (Throwable ex) {
throw new IllegalArgumentException("Failed to deserialize cache value '" + storeValue + "'", ex);
@@ -215,10 +216,10 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
}
private Object deserializeValue(Object storeValue) throws IOException {
private Object deserializeValue(SerializationDelegate serialization, Object storeValue) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream((byte[]) storeValue);
try {
return this.serialization.deserialize(in);
return serialization.deserialize(in);
}
finally {
in.close();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,6 +21,7 @@ import java.util.concurrent.ConcurrentMap;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -41,10 +42,12 @@ public class ConcurrentMapCacheFactoryBean
private String name = "";
@Nullable
private ConcurrentMap<Object, Object> store;
private boolean allowNullValues = true;
@Nullable
private ConcurrentMapCache cache;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -197,7 +197,8 @@ class CacheAdviceParser extends AbstractSingleBeanDefinitionParser {
private String method;
private String[] caches = null;
@Nullable
private String[] caches;
Props(Element root) {
String defaultCache = root.getAttribute("cache");
@@ -220,12 +221,12 @@ class CacheAdviceParser extends AbstractSingleBeanDefinitionParser {
if (StringUtils.hasText(cache)) {
localCaches = StringUtils.commaDelimitedListToStringArray(cache.trim());
}
else {
if (this.caches == null) {
readerCtx.error("No cache specified for " + element.getNodeName(), element);
}
if (localCaches != null) {
builder.setCacheNames(localCaches);
}
else {
readerCtx.error("No cache specified for " + element.getNodeName(), element);
}
builder.setCacheNames(localCaches);
builder.setKey(getAttributeValue(element, "key", this.key));
builder.setKeyGenerator(getAttributeValue(element, "key-generator", this.keyGenerator));
@@ -233,8 +234,8 @@ class CacheAdviceParser extends AbstractSingleBeanDefinitionParser {
builder.setCondition(getAttributeValue(element, "condition", this.condition));
if (StringUtils.hasText(builder.getKey()) && StringUtils.hasText(builder.getKeyGenerator())) {
throw new IllegalStateException("Invalid cache advice configuration on '"
+ element.toString() + "'. Both 'key' and 'keyGenerator' attributes have been set. " +
throw new IllegalStateException("Invalid cache advice configuration on '" +
element.toString() + "'. Both 'key' and 'keyGenerator' attributes have been set. " +
"These attributes are mutually exclusive: either set the SpEL expression used to" +
"compute the key at runtime or set the name of the KeyGenerator bean to use.");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2012 the original author or authors.
* Copyright 2010-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ import org.springframework.aop.support.DefaultPointcutAdvisor;
* of the Spring reference documentation for more information.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
* @see org.springframework.aop.framework.ProxyFactoryBean
* @see CacheInterceptor
@@ -44,9 +45,16 @@ public class CacheProxyFactoryBean extends AbstractSingletonProxyFactoryBean {
private final CacheInterceptor cachingInterceptor = new CacheInterceptor();
private Pointcut pointcut;
private Pointcut pointcut = Pointcut.TRUE;
/**
* Set the sources used to find cache operations.
*/
public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) {
this.cachingInterceptor.setCacheOperationSources(cacheOperationSources);
}
/**
* Set a pointcut, i.e a bean that can cause conditional invocation
* of the CacheInterceptor depending on method and attributes passed.
@@ -58,21 +66,11 @@ public class CacheProxyFactoryBean extends AbstractSingletonProxyFactoryBean {
this.pointcut = pointcut;
}
@Override
protected Object createMainInterceptor() {
this.cachingInterceptor.afterPropertiesSet();
if (this.pointcut == null) {
// Rely on default pointcut.
throw new UnsupportedOperationException();
}
return new DefaultPointcutAdvisor(this.pointcut, this.cachingInterceptor);
}
/**
* Set the sources used to find cache operations.
*/
public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) {
this.cachingInterceptor.setCacheOperationSources(cacheOperationSources);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import org.springframework.lang.Nullable;
*/
public class SimpleValueWrapper implements ValueWrapper {
@Nullable
private final Object value;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -66,6 +66,7 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
private BeanDefinitionDefaults beanDefinitionDefaults = new BeanDefinitionDefaults();
@Nullable
private String[] autowireCandidatePatterns;
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();

View File

@@ -42,6 +42,7 @@ import org.springframework.core.env.EnvironmentCapable;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.AnnotationMetadata;
@@ -97,14 +98,19 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
private final List<TypeFilter> excludeFilters = new LinkedList<>();
@Nullable
private Environment environment;
@Nullable
private ConditionEvaluator conditionEvaluator;
@Nullable
private ResourcePatternResolver resourcePatternResolver;
@Nullable
private MetadataReaderFactory metadataReaderFactory;
@Nullable
private CandidateComponentsIndex componentsIndex;
@@ -232,6 +238,9 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
@Override
public final Environment getEnvironment() {
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
return this.environment;
}
@@ -262,6 +271,13 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
* Return the ResourceLoader that this component provider uses.
*/
public final ResourceLoader getResourceLoader() {
return getResourcePatternResolver();
}
private ResourcePatternResolver getResourcePatternResolver() {
if (this.resourcePatternResolver == null) {
this.resourcePatternResolver = new PathMatchingResourcePatternResolver();
}
return this.resourcePatternResolver;
}
@@ -280,6 +296,9 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
* Return the MetadataReaderFactory used by this component provider.
*/
public final MetadataReaderFactory getMetadataReaderFactory() {
if (this.metadataReaderFactory == null) {
this.metadataReaderFactory = new CachingMetadataReaderFactory();
}
return this.metadataReaderFactory;
}
@@ -290,8 +309,8 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
* @return a corresponding Set of autodetected bean definitions
*/
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (isIndexSupported()) {
return addCandidateComponentsFromIndex(basePackage);
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
return scanCandidateComponents(basePackage);
@@ -304,12 +323,9 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
* instance is supported by it, {@code false} otherwise
* @since 5.0
*/
protected boolean isIndexSupported() {
if (this.componentsIndex == null) {
return false;
}
private boolean indexSupportsIncludeFilters() {
for (TypeFilter includeFilter : this.includeFilters) {
if (!isIndexSupportsIncludeFilter(includeFilter)) {
if (!indexSupportsIncludeFilter(includeFilter)) {
return false;
}
}
@@ -323,7 +339,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
* @since 5.0
* @see #extractStereotype(TypeFilter)
*/
protected boolean isIndexSupportsIncludeFilter(TypeFilter filter) {
private boolean indexSupportsIncludeFilter(TypeFilter filter) {
if (filter instanceof AnnotationTypeFilter) {
Class<? extends Annotation> annotation = ((AnnotationTypeFilter) filter).getAnnotationType();
return (AnnotationUtils.isAnnotationDeclaredLocally(Indexed.class, annotation) ||
@@ -341,10 +357,10 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
* @param filter the filter to handle
* @return the stereotype in the index matching this filter
* @since 5.0
* @see #isIndexSupportsIncludeFilter(TypeFilter)
* @see #indexSupportsIncludeFilter(TypeFilter)
*/
@Nullable
protected String extractStereotype(TypeFilter filter) {
private String extractStereotype(TypeFilter filter) {
if (filter instanceof AnnotationTypeFilter) {
return ((AnnotationTypeFilter) filter).getAnnotationType().getName();
}
@@ -354,7 +370,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
return null;
}
private Set<BeanDefinition> addCandidateComponentsFromIndex(String basePackage) {
private Set<BeanDefinition> addCandidateComponentsFromIndex(CandidateComponentsIndex index, String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
Set<String> types = new HashSet<>();
@@ -363,12 +379,12 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
if (stereotype == null) {
throw new IllegalArgumentException("Failed to extract stereotype from "+ filter);
}
types.addAll(this.componentsIndex.getCandidateTypes(basePackage, stereotype));
types.addAll(index.getCandidateTypes(basePackage, stereotype));
}
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (String type : types) {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(type);
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(type);
if (isCandidateComponent(metadataReader)) {
AnnotatedGenericBeanDefinition sbd = new AnnotatedGenericBeanDefinition(
metadataReader.getAnnotationMetadata());
@@ -402,7 +418,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
@@ -411,7 +427,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
@@ -462,7 +478,7 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
* @return the pattern specification to be used for package searching
*/
protected String resolveBasePackage(String basePackage) {
return ClassUtils.convertClassNameToResourcePath(this.environment.resolveRequiredPlaceholders(basePackage));
return ClassUtils.convertClassNameToResourcePath(getEnvironment().resolveRequiredPlaceholders(basePackage));
}
/**
@@ -473,12 +489,12 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
*/
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return isConditionMatch(metadataReader);
}
}
@@ -493,7 +509,8 @@ public class ClassPathScanningCandidateComponentProvider implements EnvironmentC
*/
private boolean isConditionMatch(MetadataReader metadataReader) {
if (this.conditionEvaluator == null) {
this.conditionEvaluator = new ConditionEvaluator(getRegistry(), getEnvironment(), getResourceLoader());
this.conditionEvaluator =
new ConditionEvaluator(getRegistry(), this.environment, this.resourcePatternResolver);
}
return !this.conditionEvaluator.shouldSkip(metadataReader.getAnnotationMetadata());
}

View File

@@ -143,12 +143,11 @@ import org.springframework.util.StringValueResolver;
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor
implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
// Common Annotations 1.1 Resource.lookup() available? Not present on JDK 6...
private static final Method lookupAttribute = ClassUtils.getMethodIfAvailable(Resource.class, "lookup");
@Nullable
private static Class<? extends Annotation> webServiceRefClass;
private static Class<? extends Annotation> webServiceRefClass = null;
private static Class<? extends Annotation> ejbRefClass = null;
@Nullable
private static Class<? extends Annotation> ejbRefClass;
static {
try {
@@ -180,14 +179,16 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private transient BeanFactory jndiFactory = new SimpleJndiBeanFactory();
@Nullable
private transient BeanFactory resourceFactory;
@Nullable
private transient BeanFactory beanFactory;
@Nullable
private transient StringValueResolver embeddedValueResolver;
private transient final Map<String, InjectionMetadata> injectionMetadataCache =
new ConcurrentHashMap<>(256);
private transient final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
/**
@@ -532,12 +533,13 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
*/
protected abstract class LookupElement extends InjectionMetadata.InjectedElement {
protected String name;
protected String name = "";
protected boolean isDefaultName = false;
protected Class<?> lookupType;
protected Class<?> lookupType = Object.class;
@Nullable
protected String mappedName;
public LookupElement(Member member, @Nullable PropertyDescriptor pd) {
@@ -602,10 +604,9 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
// No resource type specified... check field/method.
resourceType = getResourceType();
}
this.name = resourceName;
this.name = (resourceName != null ? resourceName : "");
this.lookupType = resourceType;
String lookupValue = (lookupAttribute != null ?
(String) ReflectionUtils.invokeMethod(lookupAttribute, resource) : null);
String lookupValue = resource.lookup();
this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
Lazy lazy = ae.getAnnotation(Lazy.class);
this.lazyLookup = (lazy != null && lazy.value());

View File

@@ -133,14 +133,17 @@ class ConditionEvaluator {
*/
private static class ConditionContextImpl implements ConditionContext {
@Nullable
private final BeanDefinitionRegistry registry;
@Nullable
private final ConfigurableListableBeanFactory beanFactory;
private final Environment environment;
private final ResourceLoader resourceLoader;
@Nullable
private final ClassLoader classLoader;
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,

View File

@@ -95,7 +95,7 @@ class ConfigurationClassEnhancer {
* container-aware callbacks capable of respecting scoping and other bean semantics.
* @return the enhanced subclass
*/
public Class<?> enhance(Class<?> configClass, ClassLoader classLoader) {
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
if (logger.isDebugEnabled()) {
logger.debug(String.format("Ignoring request to enhance %s as it has " +
@@ -118,7 +118,7 @@ class ConfigurationClassEnhancer {
/**
* Creates a new CGLIB {@link Enhancer} instance.
*/
private Enhancer newEnhancer(Class<?> superclass, ClassLoader classLoader) {
private Enhancer newEnhancer(Class<?> superclass, @Nullable ClassLoader classLoader) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(superclass);
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
@@ -210,6 +210,7 @@ class ConfigurationClassEnhancer {
*/
private static class BeanFactoryAwareGeneratorStrategy extends DefaultGeneratorStrategy {
@Nullable
private final ClassLoader classLoader;
public BeanFactoryAwareGeneratorStrategy(@Nullable ClassLoader classLoader) {

View File

@@ -133,6 +133,7 @@ class ConfigurationClassParser {
private final ImportStack importStack = new ImportStack();
@Nullable
private List<DeferredImportSelectorHolder> deferredImportSelectors;
@@ -539,8 +540,11 @@ class ConfigurationClassParser {
private void processDeferredImportSelectors() {
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null;
Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR);
if (deferredImports == null) {
return;
}
Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR);
for (DeferredImportSelectorHolder deferredImport : deferredImports) {
ConfigurationClass configClass = deferredImport.getConfigurationClass();
try {

View File

@@ -54,6 +54,7 @@ import org.springframework.context.annotation.ConfigurationClassEnhancer.Enhance
import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered;
import org.springframework.core.env.Environment;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
@@ -96,10 +97,12 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private ProblemReporter problemReporter = new FailFastProblemReporter();
@Nullable
private Environment environment;
private ResourceLoader resourceLoader = new DefaultResourceLoader();
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
@@ -110,6 +113,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
private final Set<Integer> factoriesPostProcessed = new HashSet<>();
@Nullable
private ConfigurationClassBeanDefinitionReader reader;
private boolean localBeanNameGeneratorSet = false;
@@ -193,7 +197,7 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
@Override
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
public void setResourceLoader(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.resourceLoader = resourceLoader;
if (!this.setMetadataReaderFactoryCalled) {
@@ -297,6 +301,10 @@ public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPo
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,

View File

@@ -27,6 +27,7 @@ import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* {@code @Configuration} class that registers a {@link LoadTimeWeaver} bean.
@@ -43,10 +44,13 @@ import org.springframework.lang.Nullable;
@Configuration
public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoaderAware {
@Nullable
private AnnotationAttributes enableLTW;
@Nullable
private LoadTimeWeavingConfigurer ltwConfigurer;
@Nullable
private ClassLoader beanClassLoader;
@@ -65,7 +69,7 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade
}
@Override
public void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) {
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
}
@@ -73,6 +77,7 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade
@Bean(name = ConfigurableApplicationContext.LOAD_TIME_WEAVER_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public LoadTimeWeaver loadTimeWeaver() {
Assert.state(this.beanClassLoader != null, "No ClassLoader set");
LoadTimeWeaver loadTimeWeaver = null;
if (this.ltwConfigurer != null) {
@@ -85,22 +90,24 @@ public class LoadTimeWeavingConfiguration implements ImportAware, BeanClassLoade
loadTimeWeaver = new DefaultContextLoadTimeWeaver(this.beanClassLoader);
}
AspectJWeaving aspectJWeaving = this.enableLTW.getEnum("aspectjWeaving");
switch (aspectJWeaving) {
case DISABLED:
// AJ weaving is disabled -> do nothing
break;
case AUTODETECT:
if (this.beanClassLoader.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) == null) {
// No aop.xml present on the classpath -> treat as 'disabled'
if (this.enableLTW != null) {
AspectJWeaving aspectJWeaving = this.enableLTW.getEnum("aspectjWeaving");
switch (aspectJWeaving) {
case DISABLED:
// AJ weaving is disabled -> do nothing
break;
}
// aop.xml is present on the classpath -> enable
AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader);
break;
case ENABLED:
AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader);
break;
case AUTODETECT:
if (this.beanClassLoader.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) == null) {
// No aop.xml present on the classpath -> treat as 'disabled'
break;
}
// aop.xml is present on the classpath -> enable
AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader);
break;
case ENABLED:
AspectJWeavingEnabler.enableAspectJWeaving(loadTimeWeaver, this.beanClassLoader);
break;
}
}
return loadTimeWeaver;

View File

@@ -33,6 +33,7 @@ import org.springframework.jmx.support.RegistrationPolicy;
import org.springframework.jmx.support.WebSphereMBeanServerFactoryBean;
import org.springframework.jndi.JndiLocatorDelegate;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -52,10 +53,13 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
private static final String MBEAN_EXPORTER_BEAN_NAME = "mbeanExporter";
@Nullable
private AnnotationAttributes enableMBeanExport;
@Nullable
private Environment environment;
@Nullable
private BeanFactory beanFactory;
@@ -84,14 +88,15 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AnnotationMBeanExporter mbeanExporter() {
AnnotationMBeanExporter exporter = new AnnotationMBeanExporter();
setupDomain(exporter);
setupServer(exporter);
setupRegistrationPolicy(exporter);
Assert.state(this.enableMBeanExport != null, "No EnableMBeanExport annotation found");
setupDomain(exporter, this.enableMBeanExport);
setupServer(exporter, this.enableMBeanExport);
setupRegistrationPolicy(exporter, this.enableMBeanExport);
return exporter;
}
private void setupDomain(AnnotationMBeanExporter exporter) {
String defaultDomain = this.enableMBeanExport.getString("defaultDomain");
private void setupDomain(AnnotationMBeanExporter exporter, AnnotationAttributes enableMBeanExport) {
String defaultDomain = enableMBeanExport.getString("defaultDomain");
if (StringUtils.hasLength(defaultDomain) && this.environment != null) {
defaultDomain = this.environment.resolvePlaceholders(defaultDomain);
}
@@ -100,12 +105,13 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
}
}
private void setupServer(AnnotationMBeanExporter exporter) {
String server = this.enableMBeanExport.getString("server");
private void setupServer(AnnotationMBeanExporter exporter, AnnotationAttributes enableMBeanExport) {
String server = enableMBeanExport.getString("server");
if (StringUtils.hasLength(server) && this.environment != null) {
server = this.environment.resolvePlaceholders(server);
}
if (StringUtils.hasText(server)) {
Assert.state(this.beanFactory != null, "No BeanFactory set");
exporter.setServer(this.beanFactory.getBean(server, MBeanServer.class));
}
else {
@@ -119,8 +125,8 @@ public class MBeanExportConfiguration implements ImportAware, EnvironmentAware,
}
}
private void setupRegistrationPolicy(AnnotationMBeanExporter exporter) {
RegistrationPolicy registrationPolicy = this.enableMBeanExport.getEnum("registration");
private void setupRegistrationPolicy(AnnotationMBeanExporter exporter, AnnotationAttributes enableMBeanExport) {
RegistrationPolicy registrationPolicy = enableMBeanExport.getEnum("registration");
exporter.setRegistrationPolicy(registrationPolicy);
}

View File

@@ -65,8 +65,10 @@ public abstract class AbstractApplicationEventMulticaster
final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = new ConcurrentHashMap<>(64);
@Nullable
private ClassLoader beanClassLoader;
@Nullable
private BeanFactory beanFactory;
private Object retrievalMutex = this.defaultRetriever;
@@ -300,6 +302,7 @@ public abstract class AbstractApplicationEventMulticaster
private final ResolvableType eventType;
@Nullable
private final Class<?> sourceType;
public ListenerCacheKey(ResolvableType eventType, @Nullable Class<?> sourceType) {

View File

@@ -71,14 +71,17 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
private final List<ResolvableType> declaredEventTypes;
@Nullable
private final String condition;
private final int order;
private final AnnotatedElementKey methodKey;
@Nullable
private ApplicationContext applicationContext;
@Nullable
private EventExpressionEvaluator evaluator;
@@ -291,6 +294,7 @@ public class ApplicationListenerMethodAdapter implements GenericApplicationListe
* annotation or any matching attribute on a composed annotation that
* is meta-annotated with {@code @EventListener}.
*/
@Nullable
protected String getCondition() {
return this.condition;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,8 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* {@link MethodInterceptor Interceptor} that publishes an
@@ -48,8 +50,10 @@ import org.springframework.context.ApplicationEventPublisherAware;
public class EventPublicationInterceptor
implements MethodInterceptor, ApplicationEventPublisherAware, InitializingBean {
@Nullable
private Constructor<?> applicationEventClassConstructor;
@Nullable
private ApplicationEventPublisher applicationEventPublisher;
@@ -64,15 +68,14 @@ public class EventPublicationInterceptor
*/
public void setApplicationEventClass(Class<?> applicationEventClass) {
if (ApplicationEvent.class == applicationEventClass ||
!ApplicationEvent.class.isAssignableFrom(applicationEventClass)) {
throw new IllegalArgumentException("applicationEventClass needs to extend ApplicationEvent");
!ApplicationEvent.class.isAssignableFrom(applicationEventClass)) {
throw new IllegalArgumentException("'applicationEventClass' needs to extend ApplicationEvent");
}
try {
this.applicationEventClassConstructor =
applicationEventClass.getConstructor(new Class<?>[] {Object.class});
this.applicationEventClassConstructor = applicationEventClass.getConstructor(Object.class);
}
catch (NoSuchMethodException ex) {
throw new IllegalArgumentException("applicationEventClass [" +
throw new IllegalArgumentException("ApplicationEvent class [" +
applicationEventClass.getName() + "] does not have the required Object constructor: " + ex);
}
}
@@ -85,7 +88,7 @@ public class EventPublicationInterceptor
@Override
public void afterPropertiesSet() throws Exception {
if (this.applicationEventClassConstructor == null) {
throw new IllegalArgumentException("applicationEventClass is required");
throw new IllegalArgumentException("Property 'applicationEventClass' is required");
}
}
@@ -94,8 +97,11 @@ public class EventPublicationInterceptor
public Object invoke(MethodInvocation invocation) throws Throwable {
Object retVal = invocation.proceed();
Assert.state(this.applicationEventClassConstructor != null, "No ApplicationEvent class set");
ApplicationEvent event = (ApplicationEvent)
this.applicationEventClassConstructor.newInstance(new Object[] {invocation.getThis()});
this.applicationEventClassConstructor.newInstance(invocation.getThis());
Assert.state(this.applicationEventPublisher != null, "No ApplicationEventPublisher available");
this.applicationEventPublisher.publishEvent(event);
return retVal;

View File

@@ -37,6 +37,7 @@ public class GenericApplicationListenerAdapter implements GenericApplicationList
private final ApplicationListener<ApplicationEvent> delegate;
@Nullable
private final ResolvableType declaredEventType;

View File

@@ -48,8 +48,10 @@ import org.springframework.util.ErrorHandler;
*/
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
@Nullable
private Executor taskExecutor;
@Nullable
private ErrorHandler errorHandler;

View File

@@ -38,6 +38,7 @@ public class SourceFilteringListener implements GenericApplicationListener, Smar
private final Object source;
@Nullable
private GenericApplicationListener delegate;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.context.expression;
import java.lang.reflect.AnnotatedElement;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -34,6 +35,7 @@ public final class AnnotatedElementKey implements Comparable<AnnotatedElementKey
private final AnnotatedElement element;
@Nullable
private final Class<?> targetClass;
@@ -41,7 +43,7 @@ public final class AnnotatedElementKey implements Comparable<AnnotatedElementKey
* Create a new instance with the specified {@link AnnotatedElement} and
* optional target {@link Class}.
*/
public AnnotatedElementKey(AnnotatedElement element, Class<?> targetClass) {
public AnnotatedElementKey(AnnotatedElement element, @Nullable Class<?> targetClass) {
Assert.notNull(element, "AnnotatedElement must not be null");
this.element = element;
this.targetClass = targetClass;
@@ -75,6 +77,9 @@ public final class AnnotatedElementKey implements Comparable<AnnotatedElementKey
public int compareTo(AnnotatedElementKey other) {
int result = this.element.toString().compareTo(other.element.toString());
if (result == 0 && this.targetClass != null) {
if (other.targetClass == null) {
return 1;
}
result = this.targetClass.getName().compareTo(other.targetClass.getName());
}
return result;

View File

@@ -135,7 +135,7 @@ public abstract class CachedExpressionEvaluator {
@Override
public int compareTo(ExpressionKey other) {
int result = this.element.toString().compareTo(other.element.toString());
if (result == 0 && this.expression != null) {
if (result == 0) {
result = this.expression.compareTo(other.expression);
}
return result;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -95,7 +95,7 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
* using it as the basis for expression compilation.
* @param beanClassLoader the factory's bean class loader
*/
public StandardBeanExpressionResolver(ClassLoader beanClassLoader) {
public StandardBeanExpressionResolver(@Nullable ClassLoader beanClassLoader) {
this.expressionParser = new SpelExpressionParser(new SpelParserConfiguration(null, beanClassLoader));
}

View File

@@ -51,9 +51,11 @@ public abstract class LocaleContextHolder {
new NamedInheritableThreadLocal<>("LocaleContext");
// Shared default locale at the framework level
@Nullable
private static Locale defaultLocale;
// Shared default time zone at the framework level
@Nullable
private static TimeZone defaultTimeZone;

View File

@@ -32,6 +32,7 @@ import org.springframework.lang.Nullable;
*/
public class SimpleLocaleContext implements LocaleContext {
@Nullable
private final Locale locale;
@@ -45,6 +46,7 @@ public class SimpleLocaleContext implements LocaleContext {
}
@Override
@Nullable
public Locale getLocale() {
return this.locale;
}

View File

@@ -36,6 +36,7 @@ import org.springframework.lang.Nullable;
*/
public class SimpleTimeZoneAwareLocaleContext extends SimpleLocaleContext implements TimeZoneAwareLocaleContext {
@Nullable
private final TimeZone timeZone;
@@ -53,6 +54,7 @@ public class SimpleTimeZoneAwareLocaleContext extends SimpleLocaleContext implem
@Override
@Nullable
public TimeZone getTimeZone() {
return this.timeZone;
}

View File

@@ -167,9 +167,11 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
private String displayName = ObjectUtils.identityToString(this);
/** Parent context */
@Nullable
private ApplicationContext parent;
/** Environment used by this context */
@Nullable
private ConfigurableEnvironment environment;
/** BeanFactoryPostProcessors to apply on refresh */
@@ -188,24 +190,29 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
private final Object startupShutdownMonitor = new Object();
/** Reference to the JVM shutdown hook, if registered */
@Nullable
private Thread shutdownHook;
/** ResourcePatternResolver used by this context */
private ResourcePatternResolver resourcePatternResolver;
/** LifecycleProcessor for managing the lifecycle of beans within this context */
@Nullable
private LifecycleProcessor lifecycleProcessor;
/** MessageSource we delegate our implementation of this interface to */
@Nullable
private MessageSource messageSource;
/** Helper class used in event publishing */
@Nullable
private ApplicationEventMulticaster applicationEventMulticaster;
/** Statically specified listeners */
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
/** ApplicationEvents published early */
@Nullable
private Set<ApplicationEvent> earlyApplicationEvents;
@@ -275,6 +282,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
* (that is, this context is the root of the context hierarchy).
*/
@Override
@Nullable
public ApplicationContext getParent() {
return this.parent;
}

View File

@@ -64,8 +64,10 @@ import org.springframework.util.ObjectUtils;
*/
public abstract class AbstractMessageSource extends MessageSourceSupport implements HierarchicalMessageSource {
@Nullable
private MessageSource parentMessageSource;
@Nullable
private Properties commonMessages;
private boolean useCodeAsDefaultMessage = false;
@@ -77,6 +79,7 @@ public abstract class AbstractMessageSource extends MessageSourceSupport impleme
}
@Override
@Nullable
public MessageSource getParentMessageSource() {
return this.parentMessageSource;
}

View File

@@ -64,11 +64,14 @@ import org.springframework.lang.Nullable;
*/
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
@Nullable
private Boolean allowBeanDefinitionOverriding;
@Nullable
private Boolean allowCircularReferences;
/** Bean factory for this context */
@Nullable
private DefaultListableBeanFactory beanFactory;
/** Synchronization monitor for the internal BeanFactory */
@@ -149,8 +152,10 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
@Override
protected final void closeBeanFactory() {
synchronized (this.beanFactoryMonitor) {
this.beanFactory.setSerializationId(null);
this.beanFactory = null;
if (this.beanFactory != null) {
this.beanFactory.setSerializationId(null);
this.beanFactory = null;
}
}
}

View File

@@ -39,6 +39,7 @@ import org.springframework.util.StringUtils;
public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
implements BeanNameAware, InitializingBean {
@Nullable
private String[] configLocations;
private boolean setIdCalled = false;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcess
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
@@ -46,6 +47,7 @@ class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor,
private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class);
@Nullable
private transient final AbstractApplicationContext applicationContext;
private transient final Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);

View File

@@ -52,9 +52,11 @@ public abstract class ApplicationObjectSupport implements ApplicationContextAwar
protected final Log logger = LogFactory.getLog(getClass());
/** ApplicationContext this object runs in */
@Nullable
private ApplicationContext applicationContext;
/** MessageSourceAccessor for easy message access */
@Nullable
private MessageSourceAccessor messageSourceAccessor;

View File

@@ -23,6 +23,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.springframework.core.DecoratingClassLoader;
import org.springframework.core.OverridingClassLoader;
import org.springframework.core.SmartClassLoader;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils;
/**
@@ -59,7 +60,7 @@ class ContextTypeMatchClassLoader extends DecoratingClassLoader implements Smart
private final Map<String, byte[]> bytesCache = new ConcurrentHashMap<>(256);
public ContextTypeMatchClassLoader(ClassLoader parent) {
public ContextTypeMatchClassLoader(@Nullable ClassLoader parent) {
super(parent);
}

View File

@@ -35,10 +35,13 @@ import org.springframework.util.StringUtils;
@SuppressWarnings("serial")
public class DefaultMessageSourceResolvable implements MessageSourceResolvable, Serializable {
@Nullable
private final String[] codes;
@Nullable
private final Object[] arguments;
@Nullable
private final String defaultMessage;
@@ -109,16 +112,19 @@ public class DefaultMessageSourceResolvable implements MessageSourceResolvable,
}
@Override
@Nullable
public String[] getCodes() {
return this.codes;
}
@Override
@Nullable
public Object[] getArguments() {
return this.arguments;
}
@Override
@Nullable
public String getDefaultMessage() {
return this.defaultMessage;
}

View File

@@ -37,6 +37,7 @@ import org.springframework.lang.Nullable;
*/
public class DelegatingMessageSource extends MessageSourceSupport implements HierarchicalMessageSource {
@Nullable
private MessageSource parentMessageSource;
@@ -46,6 +47,7 @@ public class DelegatingMessageSource extends MessageSourceSupport implements Hie
}
@Override
@Nullable
public MessageSource getParentMessageSource() {
return this.parentMessageSource;
}

View File

@@ -29,6 +29,7 @@ import org.springframework.util.StringValueResolver;
*/
public class EmbeddedValueResolutionSupport implements EmbeddedValueResolverAware {
@Nullable
private StringValueResolver embeddedValueResolver;

View File

@@ -93,6 +93,7 @@ public class GenericApplicationContext extends AbstractApplicationContext implem
private final DefaultListableBeanFactory beanFactory;
@Nullable
private ResourceLoader resourceLoader;
private boolean customClassLoader = false;

View File

@@ -56,9 +56,9 @@ public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAwar
public static final String MBEAN_APPLICATION_KEY = "application";
private static final Set<ConfigurableApplicationContext> applicationContexts =
new LinkedHashSet<>();
private static final Set<ConfigurableApplicationContext> applicationContexts = new LinkedHashSet<>();
@Nullable
private static String applicationName;
@@ -103,6 +103,7 @@ public class LiveBeansView implements LiveBeansViewMBean, ApplicationContextAwar
}
@Nullable
private ConfigurableApplicationContext applicationContext;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,8 +39,10 @@ public class MessageSourceAccessor {
private final MessageSource messageSource;
@Nullable
private final Locale defaultLocale;
/**
* Create a new MessageSourceAccessor, using LocaleContextHolder's locale
* as default locale.
@@ -62,6 +64,7 @@ public class MessageSourceAccessor {
this.defaultLocale = defaultLocale;
}
/**
* Return the default locale to use if no explicit locale has been given.
* <p>The default implementation returns the default locale passed into the

View File

@@ -31,6 +31,7 @@ import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.PropertySources;
import org.springframework.core.env.PropertySourcesPropertyResolver;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringValueResolver;
@@ -75,10 +76,13 @@ public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerS
public static final String ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME = "environmentProperties";
@Nullable
private MutablePropertySources propertySources;
@Nullable
private PropertySources appliedPropertySources;
@Nullable
private Environment environment;

View File

@@ -92,6 +92,7 @@ public class ReloadableResourceBundleMessageSource extends AbstractResourceBased
private static final String XML_SUFFIX = ".xml";
@Nullable
private Properties fileEncodings;
private boolean concurrentRefresh = true;
@@ -549,6 +550,7 @@ public class ReloadableResourceBundleMessageSource extends AbstractResourceBased
*/
protected class PropertiesHolder {
@Nullable
private final Properties properties;
private final long fileTimestamp;

View File

@@ -36,6 +36,7 @@ import java.util.Set;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
@@ -66,8 +67,10 @@ import org.springframework.util.ClassUtils;
*/
public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSource implements BeanClassLoaderAware {
@Nullable
private ClassLoader bundleClassLoader;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
/**
@@ -77,8 +80,7 @@ public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSou
* This allows for very efficient hash lookups, significantly faster
* than the ResourceBundle class's own cache.
*/
private final Map<String, Map<Locale, ResourceBundle>> cachedResourceBundles =
new HashMap<>();
private final Map<String, Map<Locale, ResourceBundle>> cachedResourceBundles = new HashMap<>();
/**
* Cache to hold already generated MessageFormats.
@@ -88,8 +90,7 @@ public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSou
* very efficient hash lookups without concatenated keys.
* @see #getMessageFormat
*/
private final Map<ResourceBundle, Map<String, Map<Locale, MessageFormat>>> cachedBundleMessageFormats =
new HashMap<>();
private final Map<ResourceBundle, Map<String, Map<Locale, MessageFormat>>> cachedBundleMessageFormats = new HashMap<>();
/**
@@ -109,6 +110,7 @@ public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSou
* <p>Default is the containing BeanFactory's bean ClassLoader.
* @see #setBundleClassLoader
*/
@Nullable
protected ClassLoader getBundleClassLoader() {
return (this.bundleClassLoader != null ? this.bundleClassLoader : this.beanClassLoader);
}
@@ -214,7 +216,9 @@ public class ResourceBundleMessageSource extends AbstractResourceBasedMessageSou
* @see #getBundleClassLoader()
*/
protected ResourceBundle doGetBundle(String basename, Locale locale) throws MissingResourceException {
return ResourceBundle.getBundle(basename, locale, getBundleClassLoader(), new MessageSourceControl());
ClassLoader classLoader = getBundleClassLoader();
Assert.state(classLoader != null, "No bundle ClassLoader set");
return ResourceBundle.getBundle(basename, locale, classLoader, new MessageSourceControl());
}
/**

View File

@@ -78,7 +78,9 @@ public class AspectJWeavingEnabler
* @param weaverToUse the LoadTimeWeaver to apply to (or {@code null} for a default weaver)
* @param beanClassLoader the class loader to create a default weaver for (if necessary)
*/
public static void enableAspectJWeaving(@Nullable LoadTimeWeaver weaverToUse, ClassLoader beanClassLoader) {
public static void enableAspectJWeaving(
@Nullable LoadTimeWeaver weaverToUse, @Nullable ClassLoader beanClassLoader) {
if (weaverToUse == null) {
if (InstrumentationLoadTimeWeaver.isInstrumentationAvailable()) {
weaverToUse = new InstrumentationLoadTimeWeaver(beanClassLoader);

View File

@@ -33,6 +33,7 @@ import org.springframework.instrument.classloading.tomcat.TomcatLoadTimeWeaver;
import org.springframework.instrument.classloading.weblogic.WebLogicLoadTimeWeaver;
import org.springframework.instrument.classloading.websphere.WebSphereLoadTimeWeaver;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
* Default {@link LoadTimeWeaver} bean for use in an application context,
@@ -58,6 +59,7 @@ public class DefaultContextLoadTimeWeaver implements LoadTimeWeaver, BeanClassLo
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private LoadTimeWeaver loadTimeWeaver;
@@ -68,6 +70,7 @@ public class DefaultContextLoadTimeWeaver implements LoadTimeWeaver, BeanClassLo
setBeanClassLoader(beanClassLoader);
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
LoadTimeWeaver serverSpecificLoadTimeWeaver = createServerSpecificLoadTimeWeaver(classLoader);
@@ -148,16 +151,19 @@ public class DefaultContextLoadTimeWeaver implements LoadTimeWeaver, BeanClassLo
@Override
public void addTransformer(ClassFileTransformer transformer) {
Assert.state(this.loadTimeWeaver != null, "Not initialized");
this.loadTimeWeaver.addTransformer(transformer);
}
@Override
public ClassLoader getInstrumentableClassLoader() {
Assert.state(this.loadTimeWeaver != null, "Not initialized");
return this.loadTimeWeaver.getInstrumentableClassLoader();
}
@Override
public ClassLoader getThrowawayClassLoader() {
Assert.state(this.loadTimeWeaver != null, "Not initialized");
return this.loadTimeWeaver.getThrowawayClassLoader();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,8 +43,10 @@ import org.springframework.util.Assert;
*/
public class LoadTimeWeaverAwareProcessor implements BeanPostProcessor, BeanFactoryAware {
@Nullable
private LoadTimeWeaver loadTimeWeaver;
@Nullable
private BeanFactory beanFactory;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,11 +51,13 @@ public abstract class AbstractSlsbInvokerInterceptor extends JndiObjectLocator
* The EJB's home object, potentially cached.
* The type must be Object as it could be either EJBHome or EJBLocalHome.
*/
@Nullable
private Object cachedHome;
/**
* The no-arg create() method required on EJB homes, potentially cached.
*/
@Nullable
private Method createMethod;
private final Object homeMonitor = new Object();

View File

@@ -21,6 +21,7 @@ import javax.naming.NamingException;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -52,11 +53,14 @@ public class LocalStatelessSessionProxyFactoryBean extends LocalSlsbInvokerInter
implements FactoryBean<Object>, BeanClassLoaderAware {
/** The business interface of the EJB we're proxying */
@Nullable
private Class<?> businessInterface;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
/** EJBLocalObject */
@Nullable
private Object proxy;
@@ -73,6 +77,7 @@ public class LocalStatelessSessionProxyFactoryBean extends LocalSlsbInvokerInter
/**
* Return the business interface of the EJB we're proxying.
*/
@Nullable
public Class<?> getBusinessInterface() {
return this.businessInterface;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import javax.naming.NamingException;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.lang.Nullable;
import org.springframework.remoting.RemoteLookupFailureException;
import org.springframework.remoting.rmi.RmiClientInterceptorUtils;
@@ -66,6 +67,7 @@ public class SimpleRemoteSlsbInvokerInterceptor extends AbstractRemoteSlsbInvoke
private boolean cacheSessionBean = false;
@Nullable
private Object beanInstance;
private final Object beanInstanceMonitor = new Object();

View File

@@ -21,6 +21,7 @@ import javax.naming.NamingException;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -62,11 +63,14 @@ public class SimpleRemoteStatelessSessionProxyFactoryBean extends SimpleRemoteSl
implements FactoryBean<Object>, BeanClassLoaderAware {
/** The business interface of the EJB we're proxying */
@Nullable
private Class<?> businessInterface;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
/** EJBObject */
@Nullable
private Object proxy;
@@ -87,6 +91,7 @@ public class SimpleRemoteStatelessSessionProxyFactoryBean extends SimpleRemoteSl
/**
* Return the business interface of the EJB we're proxying.
*/
@Nullable
public Class<?> getBusinessInterface() {
return this.businessInterface;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import java.util.TimeZone;
import org.springframework.format.Formatter;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -55,14 +56,18 @@ public class DateFormatter implements Formatter<Date> {
}
@Nullable
private String pattern;
private int style = DateFormat.DEFAULT;
@Nullable
private String stylePattern;
@Nullable
private ISO iso;
@Nullable
private TimeZone timeZone;
private boolean lenient = false;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.format.FormatterRegistrar;
import org.springframework.format.FormatterRegistry;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -42,6 +43,7 @@ import org.springframework.util.Assert;
*/
public class DateFormatterRegistrar implements FormatterRegistrar {
@Nullable
private DateFormatter dateFormatter;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -44,12 +45,16 @@ import org.springframework.util.StringUtils;
*/
public class DateTimeFormatterFactory {
@Nullable
private String pattern;
@Nullable
private ISO iso;
@Nullable
private String style;
@Nullable
private TimeZone timeZone;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2013 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,8 +39,10 @@ import org.springframework.lang.Nullable;
*/
public class JodaTimeContext {
@Nullable
private Chronology chronology;
@Nullable
private DateTimeZone timeZone;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,8 +37,10 @@ import org.springframework.lang.Nullable;
*/
public class DateTimeContext {
@Nullable
private Chronology chronology;
@Nullable
private ZoneId timeZone;

View File

@@ -46,14 +46,19 @@ import org.springframework.util.StringUtils;
*/
public class DateTimeFormatterFactory {
@Nullable
private String pattern;
@Nullable
private ISO iso;
@Nullable
private FormatStyle dateStyle;
@Nullable
private FormatStyle timeStyle;
@Nullable
private TimeZone timeZone;

View File

@@ -24,6 +24,8 @@ import java.text.ParseException;
import java.util.Currency;
import java.util.Locale;
import org.springframework.lang.Nullable;
/**
* A BigDecimal formatter for number values in currency style.
*
@@ -41,10 +43,13 @@ public class CurrencyStyleFormatter extends AbstractNumberFormatter {
private int fractionDigits = 2;
@Nullable
private RoundingMode roundingMode;
@Nullable
private Currency currency;
@Nullable
private String pattern;

View File

@@ -20,6 +20,8 @@ import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import org.springframework.lang.Nullable;
/**
* A general-purpose number formatter using NumberFormat's number style.
*
@@ -36,6 +38,7 @@ import java.util.Locale;
*/
public class NumberStyleFormatter extends AbstractNumberFormatter {
@Nullable
private String pattern;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ import javax.money.format.MonetaryAmountFormat;
import javax.money.format.MonetaryFormats;
import org.springframework.format.Formatter;
import org.springframework.lang.Nullable;
/**
* Formatter for JSR-354 {@link javax.money.MonetaryAmount} values,
@@ -34,6 +35,7 @@ import org.springframework.format.Formatter;
*/
public class MonetaryAmountFormatter implements Formatter<MonetaryAmount> {
@Nullable
private String formatName;

View File

@@ -51,6 +51,7 @@ import org.springframework.util.StringValueResolver;
public class FormattingConversionService extends GenericConversionService
implements FormatterRegistry, EmbeddedValueResolverAware {
@Nullable
private StringValueResolver embeddedValueResolver;
private final Map<AnnotationConverterKey, GenericConverter> cachedPrinters = new ConcurrentHashMap<>(64);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import org.springframework.format.FormatterRegistrar;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.Parser;
import org.springframework.format.Printer;
import org.springframework.lang.Nullable;
import org.springframework.util.StringValueResolver;
/**
@@ -63,16 +64,21 @@ import org.springframework.util.StringValueResolver;
public class FormattingConversionServiceFactoryBean
implements FactoryBean<FormattingConversionService>, EmbeddedValueResolverAware, InitializingBean {
@Nullable
private Set<?> converters;
@Nullable
private Set<?> formatters;
@Nullable
private Set<FormatterRegistrar> formatterRegistrars;
private boolean registerDefaultFormatters = true;
@Nullable
private StringValueResolver embeddedValueResolver;
@Nullable
private FormattingConversionService conversionService;
@@ -134,17 +140,17 @@ public class FormattingConversionServiceFactoryBean
public void afterPropertiesSet() {
this.conversionService = new DefaultFormattingConversionService(this.embeddedValueResolver, this.registerDefaultFormatters);
ConversionServiceFactory.registerConverters(this.converters, this.conversionService);
registerFormatters();
registerFormatters(this.conversionService);
}
private void registerFormatters() {
private void registerFormatters(FormattingConversionService conversionService) {
if (this.formatters != null) {
for (Object formatter : this.formatters) {
if (formatter instanceof Formatter<?>) {
this.conversionService.addFormatter((Formatter<?>) formatter);
conversionService.addFormatter((Formatter<?>) formatter);
}
else if (formatter instanceof AnnotationFormatterFactory<?>) {
this.conversionService.addFormatterForFieldAnnotation((AnnotationFormatterFactory<?>) formatter);
conversionService.addFormatterForFieldAnnotation((AnnotationFormatterFactory<?>) formatter);
}
else {
throw new IllegalArgumentException(
@@ -154,7 +160,7 @@ public class FormattingConversionServiceFactoryBean
}
if (this.formatterRegistrars != null) {
for (FormatterRegistrar registrar : this.formatterRegistrars) {
registrar.registerFormatters(this.conversionService);
registrar.registerFormatters(conversionService);
}
}
}

View File

@@ -54,8 +54,10 @@ public class InstrumentationLoadTimeWeaver implements LoadTimeWeaver {
InstrumentationLoadTimeWeaver.class.getClassLoader());
@Nullable
private final ClassLoader classLoader;
@Nullable
private final Instrumentation instrumentation;
private final List<ClassFileTransformer> transformers = new ArrayList<>(4);
@@ -115,7 +117,7 @@ public class InstrumentationLoadTimeWeaver implements LoadTimeWeaver {
*/
public void removeTransformers() {
synchronized (this.transformers) {
if (!this.transformers.isEmpty()) {
if (this.instrumentation != null && !this.transformers.isEmpty()) {
for (int i = this.transformers.size() - 1; i >= 0; i--) {
this.instrumentation.removeTransformer(this.transformers.get(i));
}
@@ -167,9 +169,12 @@ public class InstrumentationLoadTimeWeaver implements LoadTimeWeaver {
private final ClassFileTransformer targetTransformer;
@Nullable
private final ClassLoader targetClassLoader;
public FilteringClassFileTransformer(ClassFileTransformer targetTransformer, ClassLoader targetClassLoader) {
public FilteringClassFileTransformer(
ClassFileTransformer targetTransformer, @Nullable ClassLoader targetClassLoader) {
this.targetTransformer = targetTransformer;
this.targetClassLoader = targetClassLoader;
}
@@ -179,7 +184,7 @@ public class InstrumentationLoadTimeWeaver implements LoadTimeWeaver {
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if (!this.targetClassLoader.equals(loader)) {
if (this.targetClassLoader != loader) {
return null;
}
return this.targetTransformer.transform(

View File

@@ -76,6 +76,7 @@ public class ReflectiveLoadTimeWeaver implements LoadTimeWeaver {
private final Method addTransformerMethod;
@Nullable
private final Method getThrowawayClassLoaderMethod;
@@ -97,22 +98,26 @@ public class ReflectiveLoadTimeWeaver implements LoadTimeWeaver {
public ReflectiveLoadTimeWeaver(@Nullable ClassLoader classLoader) {
Assert.notNull(classLoader, "ClassLoader must not be null");
this.classLoader = classLoader;
this.addTransformerMethod = ClassUtils.getMethodIfAvailable(
Method addTransformerMethod = ClassUtils.getMethodIfAvailable(
this.classLoader.getClass(), ADD_TRANSFORMER_METHOD_NAME, ClassFileTransformer.class);
if (this.addTransformerMethod == null) {
if (addTransformerMethod == null) {
throw new IllegalStateException(
"ClassLoader [" + classLoader.getClass().getName() + "] does NOT provide an " +
"'addTransformer(ClassFileTransformer)' method.");
}
this.getThrowawayClassLoaderMethod = ClassUtils.getMethodIfAvailable(
this.addTransformerMethod = addTransformerMethod;
Method getThrowawayClassLoaderMethod = ClassUtils.getMethodIfAvailable(
this.classLoader.getClass(), GET_THROWAWAY_CLASS_LOADER_METHOD_NAME);
// getThrowawayClassLoader method is optional
if (this.getThrowawayClassLoaderMethod == null) {
if (getThrowawayClassLoaderMethod == null) {
if (logger.isInfoEnabled()) {
logger.info("The ClassLoader [" + classLoader.getClass().getName() + "] does NOT provide a " +
"'getThrowawayClassLoader()' method; SimpleThrowawayClassLoader will be used instead.");
}
}
this.getThrowawayClassLoaderMethod = getThrowawayClassLoaderMethod;
}

View File

@@ -39,6 +39,7 @@ import org.springframework.util.Assert;
*/
public class WeavingTransformer {
@Nullable
private final ClassLoader classLoader;
private final List<ClassFileTransformer> transformers = new ArrayList<>();

View File

@@ -67,6 +67,7 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver {
public JBossLoadTimeWeaver(@Nullable ClassLoader classLoader) {
Assert.notNull(classLoader, "ClassLoader must not be null");
this.classLoader = classLoader;
try {
Field transformer = ReflectionUtils.findField(classLoader.getClass(), "transformer");
if (transformer == null) {
@@ -74,20 +75,23 @@ public class JBossLoadTimeWeaver implements LoadTimeWeaver {
classLoader.getClass().getName());
}
transformer.setAccessible(true);
this.delegatingTransformer = transformer.get(classLoader);
if (!this.delegatingTransformer.getClass().getName().equals(DELEGATING_TRANSFORMER_CLASS_NAME)) {
throw new IllegalStateException(
"Transformer not of the expected type DelegatingClassFileTransformer: " +
this.delegatingTransformer.getClass().getName());
}
this.addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(),
Method addTransformer = ReflectionUtils.findMethod(this.delegatingTransformer.getClass(),
"addTransformer", ClassFileTransformer.class);
if (this.addTransformer == null) {
if (addTransformer == null) {
throw new IllegalArgumentException(
"Could not find 'addTransformer' method on JBoss DelegatingClassFileTransformer: " +
this.delegatingTransformer.getClass().getName());
}
this.addTransformer.setAccessible(true);
addTransformer.setAccessible(true);
this.addTransformer = addTransformer;
}
catch (Throwable ex) {
throw new IllegalStateException("Could not initialize JBoss LoadTimeWeaver", ex);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,6 +40,7 @@ class ConnectorDelegate {
private static final Log logger = LogFactory.getLog(ConnectorDelegate.class);
@Nullable
private JMXConnector connector;

View File

@@ -23,6 +23,7 @@ import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.management.Attribute;
@@ -62,6 +63,7 @@ import org.springframework.core.ResolvableType;
import org.springframework.jmx.support.JmxUtils;
import org.springframework.jmx.support.ObjectNameManager;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
@@ -93,35 +95,44 @@ public class MBeanClientInterceptor
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private MBeanServerConnection server;
@Nullable
private JMXServiceURL serviceUrl;
@Nullable
private Map<String, ?> environment;
@Nullable
private String agentId;
private boolean connectOnStartup = true;
private boolean refreshOnConnectFailure = false;
@Nullable
private ObjectName objectName;
private boolean useStrictCasing = true;
@Nullable
private Class<?> managementInterface;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
private final ConnectorDelegate connector = new ConnectorDelegate();
@Nullable
private MBeanServerConnection serverToUse;
@Nullable
private MBeanServerInvocationHandler invocationHandler;
private Map<String, MBeanAttributeInfo> allowedAttributes;
private Map<String, MBeanAttributeInfo> allowedAttributes = Collections.emptyMap();
private Map<MethodCacheKey, MBeanOperationInfo> allowedOperations;
private Map<MethodCacheKey, MBeanOperationInfo> allowedOperations = Collections.emptyMap();
private final Map<Method, String[]> signatureCache = new HashMap<>();
@@ -158,6 +169,7 @@ public class MBeanClientInterceptor
* "environment[myKey]". This is particularly useful for
* adding or overriding entries in child bean definitions.
*/
@Nullable
public Map<String, ?> getEnvironment() {
return this.environment;
}
@@ -231,7 +243,7 @@ public class MBeanClientInterceptor
}
@Override
public void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) {
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
}
@@ -266,6 +278,7 @@ public class MBeanClientInterceptor
}
this.invocationHandler = null;
if (this.useStrictCasing) {
Assert.state(this.objectName != null, "No ObjectName set");
// Use the JDK's own MBeanServerInvocationHandler, in particular for native MXBean support.
this.invocationHandler = new MBeanServerInvocationHandler(this.serverToUse, this.objectName,
(this.managementInterface != null && JMX.isMXBeanInterface(this.managementInterface)));
@@ -273,7 +286,7 @@ public class MBeanClientInterceptor
else {
// Non-strict casing can only be achieved through custom invocation handling.
// Only partial MXBean support available!
retrieveMBeanInfo();
retrieveMBeanInfo(this.serverToUse);
}
}
}
@@ -282,9 +295,9 @@ public class MBeanClientInterceptor
* This information is used by the proxy when determining whether an invocation matches
* a valid operation or attribute on the management interface of the managed resource.
*/
private void retrieveMBeanInfo() throws MBeanInfoRetrievalException {
private void retrieveMBeanInfo(MBeanServerConnection server) throws MBeanInfoRetrievalException {
try {
MBeanInfo info = this.serverToUse.getMBeanInfo(this.objectName);
MBeanInfo info = server.getMBeanInfo(this.objectName);
MBeanAttributeInfo[] attributeInfo = info.getAttributes();
this.allowedAttributes = new HashMap<>(attributeInfo.length);
@@ -401,7 +414,7 @@ public class MBeanClientInterceptor
protected Object doInvoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
try {
Object result = null;
Object result;
if (this.invocationHandler != null) {
result = this.invocationHandler.invoke(invocation.getThis(), method, invocation.getArguments());
}
@@ -468,6 +481,8 @@ public class MBeanClientInterceptor
private Object invokeAttribute(PropertyDescriptor pd, MethodInvocation invocation)
throws JMException, IOException {
Assert.state(this.serverToUse != null, "No MBeanServerConnection available");
String attributeName = JmxUtils.getAttributeName(pd, this.useStrictCasing);
MBeanAttributeInfo inf = this.allowedAttributes.get(attributeName);
// If no attribute is returned, we know that it is not defined in the
@@ -476,6 +491,7 @@ public class MBeanClientInterceptor
throw new InvalidInvocationException(
"Attribute '" + pd.getName() + "' is not exposed on the management interface");
}
if (invocation.getMethod().equals(pd.getReadMethod())) {
if (inf.isReadable()) {
return this.serverToUse.getAttribute(this.objectName, attributeName);
@@ -507,13 +523,16 @@ public class MBeanClientInterceptor
* @return the value returned by the method invocation.
*/
private Object invokeOperation(Method method, Object[] args) throws JMException, IOException {
Assert.state(this.serverToUse != null, "No MBeanServerConnection available");
MethodCacheKey key = new MethodCacheKey(method.getName(), method.getParameterTypes());
MBeanOperationInfo info = this.allowedOperations.get(key);
if (info == null) {
throw new InvalidInvocationException("Operation '" + method.getName() +
"' is not exposed on the management interface");
}
String[] signature = null;
String[] signature;
synchronized (this.signatureCache) {
signature = this.signatureCache.get(method);
if (signature == null) {
@@ -521,6 +540,7 @@ public class MBeanClientInterceptor
this.signatureCache.put(method, signature);
}
}
return this.serverToUse.invoke(this.objectName, method.getName(), args, signature);
}

View File

@@ -21,6 +21,7 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jmx.MBeanServerNotFoundException;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -48,10 +49,13 @@ import org.springframework.util.ClassUtils;
public class MBeanProxyFactoryBean extends MBeanClientInterceptor
implements FactoryBean<Object>, BeanClassLoaderAware, InitializingBean {
@Nullable
private Class<?> proxyInterface;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
@Nullable
private Object mbeanProxy;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.jmx.JmxException;
import org.springframework.jmx.MBeanServerNotFoundException;
import org.springframework.jmx.support.NotificationListenerHolder;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
/**
@@ -51,16 +52,21 @@ public class NotificationListenerRegistrar extends NotificationListenerHolder
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
private MBeanServerConnection server;
private JMXServiceURL serviceUrl;
private Map<String, ?> environment;
private String agentId;
private final ConnectorDelegate connector = new ConnectorDelegate();
@Nullable
private MBeanServerConnection server;
@Nullable
private JMXServiceURL serviceUrl;
@Nullable
private Map<String, ?> environment;
@Nullable
private String agentId;
@Nullable
private ObjectName[] actualObjectNames;
@@ -87,6 +93,7 @@ public class NotificationListenerRegistrar extends NotificationListenerHolder
* "environment[myKey]". This is particularly useful for
* adding or overriding entries in child bean definitions.
*/
@Nullable
public Map<String, ?> getEnvironment() {
return this.environment;
}
@@ -133,12 +140,14 @@ public class NotificationListenerRegistrar extends NotificationListenerHolder
}
try {
this.actualObjectNames = getResolvedObjectNames();
if (logger.isDebugEnabled()) {
logger.debug("Registering NotificationListener for MBeans " + Arrays.asList(this.actualObjectNames));
}
for (ObjectName actualObjectName : this.actualObjectNames) {
this.server.addNotificationListener(
actualObjectName, getNotificationListener(), getNotificationFilter(), getHandback());
if (this.actualObjectNames != null) {
if (logger.isDebugEnabled()) {
logger.debug("Registering NotificationListener for MBeans " + Arrays.asList(this.actualObjectNames));
}
for (ObjectName actualObjectName : this.actualObjectNames) {
this.server.addNotificationListener(
actualObjectName, getNotificationListener(), getNotificationFilter(), getHandback());
}
}
}
catch (IOException ex) {
@@ -156,7 +165,7 @@ public class NotificationListenerRegistrar extends NotificationListenerHolder
@Override
public void destroy() {
try {
if (this.actualObjectNames != null) {
if (this.server != null && this.actualObjectNames != null) {
for (ObjectName actualObjectName : this.actualObjectNames) {
try {
this.server.removeNotificationListener(

View File

@@ -141,9 +141,11 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
private static final Constants constants = new Constants(MBeanExporter.class);
/** The beans to be exposed as JMX managed resources, with JMX names as keys */
@Nullable
private Map<String, Object> beans;
/** The autodetect mode to use for this MBeanExporter */
@Nullable
private Integer autodetectMode;
/** Whether to eagerly initialize candidate beans when autodetecting MBeans */
@@ -165,19 +167,22 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
private Set<String> excludedBeans = new HashSet<>();
/** The MBeanExporterListeners registered with this exporter. */
@Nullable
private MBeanExporterListener[] listeners;
/** The NotificationListeners to register for the MBeans registered by this exporter */
@Nullable
private NotificationListenerBean[] notificationListeners;
/** Map of actually registered NotificationListeners */
private final Map<NotificationListenerBean, ObjectName[]> registeredNotificationListeners =
new LinkedHashMap<>();
private final Map<NotificationListenerBean, ObjectName[]> registeredNotificationListeners = new LinkedHashMap<>();
/** Stores the ClassLoader to use for generating lazy-init proxies */
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
/** Stores the BeanFactory for use in autodetection process */
@Nullable
private ListableBeanFactory beanFactory;
@@ -534,18 +539,17 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
if (mode == AUTODETECT_MBEAN || mode == AUTODETECT_ALL) {
// Autodetect any beans that are already MBeans.
logger.debug("Autodetecting user-defined JMX MBeans");
autodetectMBeans();
autodetect(this.beans, (beanClass, beanName) -> isMBean(beanClass));
}
// Allow the assembler a chance to vote for bean inclusion.
if ((mode == AUTODETECT_ASSEMBLER || mode == AUTODETECT_ALL) &&
this.assembler instanceof AutodetectCapableMBeanInfoAssembler) {
autodetectBeans((AutodetectCapableMBeanInfoAssembler) this.assembler);
autodetect(this.beans, ((AutodetectCapableMBeanInfoAssembler) this.assembler)::includeBean);
}
}
if (!this.beans.isEmpty()) {
this.beans.forEach((beanName, instance) ->
registerBeanNameOrInstance(instance, beanName));
this.beans.forEach((beanName, instance) -> registerBeanNameOrInstance(instance, beanName));
}
}
@@ -699,6 +703,8 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
* with the {@code MBeanServer}
*/
private ObjectName registerLazyInit(String beanName, String beanKey) throws JMException {
Assert.state(this.beanFactory != null, "No BeanFactory set");
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setProxyTargetClass(true);
proxyFactory.setFrozen(true);
@@ -863,26 +869,6 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
// Autodetection process
//---------------------------------------------------------------------
/**
* Invoked when using an {@code AutodetectCapableMBeanInfoAssembler}.
* Gives the assembler the opportunity to add additional beans from the
* {@code BeanFactory} to the list of beans to be exposed via JMX.
* <p>This implementation prevents a bean from being added to the list
* automatically if it has already been added manually, and it prevents
* certain internal classes from being registered automatically.
*/
private void autodetectBeans(final AutodetectCapableMBeanInfoAssembler assembler) {
autodetect((beanClass, beanName) -> assembler.includeBean(beanClass, beanName));
}
/**
* Attempts to detect any beans defined in the {@code ApplicationContext} that are
* valid MBeans and registers them automatically with the {@code MBeanServer}.
*/
private void autodetectMBeans() {
autodetect((beanClass, beanName) -> isMBean(beanClass));
}
/**
* Performs the actual autodetection process, delegating to an
* {@code AutodetectCallback} instance to vote on the inclusion of a
@@ -890,12 +876,14 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
* @param callback the {@code AutodetectCallback} to use when deciding
* whether to include a bean or not
*/
private void autodetect(AutodetectCallback callback) {
private void autodetect(Map<String, Object> beans, AutodetectCallback callback) {
Assert.state(this.beanFactory != null, "No BeanFactory set");
Set<String> beanNames = new LinkedHashSet<>(this.beanFactory.getBeanDefinitionCount());
beanNames.addAll(Arrays.asList(this.beanFactory.getBeanDefinitionNames()));
if (this.beanFactory instanceof ConfigurableBeanFactory) {
beanNames.addAll(Arrays.asList(((ConfigurableBeanFactory) this.beanFactory).getSingletonNames()));
}
for (String beanName : beanNames) {
if (!isExcluded(beanName) && !isBeanDefinitionAbstract(this.beanFactory, beanName)) {
try {
@@ -903,11 +891,11 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
if (beanClass != null && callback.include(beanClass, beanName)) {
boolean lazyInit = isBeanDefinitionLazyInit(this.beanFactory, beanName);
Object beanInstance = (!lazyInit ? this.beanFactory.getBean(beanName) : null);
if (!ScopedProxyUtils.isScopedTarget(beanName) && !this.beans.containsValue(beanName) &&
if (!ScopedProxyUtils.isScopedTarget(beanName) && !beans.containsValue(beanName) &&
(beanInstance == null ||
!CollectionUtils.containsInstance(this.beans.values(), beanInstance))) {
!CollectionUtils.containsInstance(beans.values(), beanInstance))) {
// Not already registered for JMX exposure.
this.beans.put(beanName, (beanInstance != null ? beanInstance : beanName));
beans.put(beanName, (beanInstance != null ? beanInstance : beanName));
if (logger.isInfoEnabled()) {
logger.info("Bean with name '" + beanName + "' has been autodetected for JMX exposure");
}
@@ -970,6 +958,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
*/
private void registerNotificationListeners() throws MBeanExportException {
if (this.notificationListeners != null) {
Assert.state(this.server != null, "No MBeanServer available");
for (NotificationListenerBean bean : this.notificationListeners) {
try {
ObjectName[] mappedObjectNames = bean.getResolvedObjectNames();
@@ -996,19 +985,21 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
* from the {@link MBeanServer}.
*/
private void unregisterNotificationListeners() {
this.registeredNotificationListeners.forEach((bean, mappedObjectNames) -> {
for (ObjectName mappedObjectName : mappedObjectNames) {
try {
this.server.removeNotificationListener(mappedObjectName, bean.getNotificationListener(),
bean.getNotificationFilter(), bean.getHandback());
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Unable to unregister NotificationListener", ex);
if (this.server != null) {
this.registeredNotificationListeners.forEach((bean, mappedObjectNames) -> {
for (ObjectName mappedObjectName : mappedObjectNames) {
try {
this.server.removeNotificationListener(mappedObjectName, bean.getNotificationListener(),
bean.getNotificationFilter(), bean.getHandback());
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Unable to unregister NotificationListener", ex);
}
}
}
}
});
});
}
this.registeredNotificationListeners.clear();
}
@@ -1096,8 +1087,10 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
@SuppressWarnings("serial")
private class NotificationPublisherAwareLazyTargetSource extends LazyInitTargetSource {
@Nullable
private ModelMBean modelMBean;
@Nullable
private ObjectName objectName;
public void setModelMBean(ModelMBean modelMBean) {
@@ -1123,6 +1116,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo
@Override
protected void postProcessTargetObject(Object targetObject) {
Assert.state(this.modelMBean != null && this.objectName != null, "Not initialized");
injectNotificationPublisherIfNecessary(targetObject, this.modelMBean, this.objectName);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,8 +24,7 @@ import org.springframework.util.Assert;
/**
* Helper class that aggregates a {@link javax.management.NotificationListener},
* a {@link javax.management.NotificationFilter}, and an arbitrary handback
* object.
* a {@link javax.management.NotificationFilter}, and an arbitrary handback object.
*
* <p>Also provides support for associating the encapsulated
* {@link javax.management.NotificationListener} with any number of

View File

@@ -50,6 +50,7 @@ import org.springframework.util.StringValueResolver;
*/
public class AnnotationJmxAttributeSource implements JmxAttributeSource, BeanFactoryAware {
@Nullable
private StringValueResolver embeddedValueResolver;

View File

@@ -25,6 +25,7 @@ import javax.management.modelmbean.ModelMBeanNotificationInfo;
import org.springframework.jmx.export.metadata.JmxMetadataUtils;
import org.springframework.jmx.export.metadata.ManagedNotification;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -37,10 +38,10 @@ import org.springframework.util.StringUtils;
*/
public abstract class AbstractConfigurableMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssembler {
@Nullable
private ModelMBeanNotificationInfo[] notificationInfos;
private final Map<String, ModelMBeanNotificationInfo[]> notificationInfoMappings =
new HashMap<>();
private final Map<String, ModelMBeanNotificationInfo[]> notificationInfoMappings = new HashMap<>();
public void setNotificationInfos(ManagedNotification[] notificationInfos) {

View File

@@ -61,14 +61,18 @@ import org.springframework.util.StringUtils;
public class InterfaceBasedMBeanInfoAssembler extends AbstractConfigurableMBeanInfoAssembler
implements BeanClassLoaderAware, InitializingBean {
@Nullable
private Class<?>[] managedInterfaces;
/** Mappings of bean keys to an array of classes */
@Nullable
private Properties interfaceMappings;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
/** Mappings of bean keys to an array of classes */
@Nullable
private Map<String, Class<?>[]> resolvedInterfaceMappings;

View File

@@ -40,12 +40,12 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* Implementation of the {@link MBeanInfoAssembler}
* interface that reads the management interface information from source level metadata.
* Implementation of the {@link MBeanInfoAssembler} interface that reads
* the management interface information from source level metadata.
*
* <p>Uses the {@link JmxAttributeSource} strategy interface, so that
* metadata can be read using any supported implementation. Out of the box,
* Spring provides an implementation based on JDK 1.5+ annotations,
* Spring provides an implementation based on annotations:
* {@code AnnotationJmxAttributeSource}.
*
* @author Rob Harrop
@@ -58,6 +58,7 @@ import org.springframework.util.StringUtils;
public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssembler
implements AutodetectCapableMBeanInfoAssembler, InitializingBean {
@Nullable
private JmxAttributeSource attributeSource;
@@ -96,6 +97,11 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
}
}
private JmxAttributeSource obtainAttributeSource() {
Assert.state(this.attributeSource != null, "No JmxAttributeSource set");
return this.attributeSource;
}
/**
* Throws an IllegalArgumentException if it encounters a JDK dynamic proxy.
@@ -118,7 +124,7 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
*/
@Override
public boolean includeBean(Class<?> beanClass, String beanName) {
return (this.attributeSource.getManagedResource(getClassToExpose(beanClass)) != null);
return (obtainAttributeSource().getManagedResource(getClassToExpose(beanClass)) != null);
}
/**
@@ -164,14 +170,14 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
* Checks to see if the given Method has the {@code ManagedAttribute} attribute.
*/
private boolean hasManagedAttribute(Method method) {
return (this.attributeSource.getManagedAttribute(method) != null);
return (obtainAttributeSource().getManagedAttribute(method) != null);
}
/**
* Checks to see if the given Method has the {@code ManagedMetric} attribute.
*/
private boolean hasManagedMetric(Method method) {
return (this.attributeSource.getManagedMetric(method) != null);
return (obtainAttributeSource().getManagedMetric(method) != null);
}
/**
@@ -179,7 +185,7 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
* @param method the method to check
*/
private boolean hasManagedOperation(Method method) {
return (this.attributeSource.getManagedOperation(method) != null);
return (obtainAttributeSource().getManagedOperation(method) != null);
}
@@ -189,7 +195,7 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
*/
@Override
protected String getDescription(Object managedBean, String beanKey) {
ManagedResource mr = this.attributeSource.getManagedResource(getClassToExpose(managedBean));
ManagedResource mr = obtainAttributeSource().getManagedResource(getClassToExpose(managedBean));
return (mr != null ? mr.getDescription() : "");
}
@@ -204,9 +210,9 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
Method writeMethod = propertyDescriptor.getWriteMethod();
ManagedAttribute getter =
(readMethod != null ? this.attributeSource.getManagedAttribute(readMethod) : null);
(readMethod != null ? obtainAttributeSource().getManagedAttribute(readMethod) : null);
ManagedAttribute setter =
(writeMethod != null ? this.attributeSource.getManagedAttribute(writeMethod) : null);
(writeMethod != null ? obtainAttributeSource().getManagedAttribute(writeMethod) : null);
if (getter != null && StringUtils.hasText(getter.getDescription())) {
return getter.getDescription();
@@ -215,7 +221,7 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
return setter.getDescription();
}
ManagedMetric metric = (readMethod != null ? this.attributeSource.getManagedMetric(readMethod) : null);
ManagedMetric metric = (readMethod != null ? obtainAttributeSource().getManagedMetric(readMethod) : null);
if (metric != null && StringUtils.hasText(metric.getDescription())) {
return metric.getDescription();
}
@@ -231,18 +237,18 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
protected String getOperationDescription(Method method, String beanKey) {
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
if (pd != null) {
ManagedAttribute ma = this.attributeSource.getManagedAttribute(method);
ManagedAttribute ma = obtainAttributeSource().getManagedAttribute(method);
if (ma != null && StringUtils.hasText(ma.getDescription())) {
return ma.getDescription();
}
ManagedMetric metric = this.attributeSource.getManagedMetric(method);
ManagedMetric metric = obtainAttributeSource().getManagedMetric(method);
if (metric != null && StringUtils.hasText(metric.getDescription())) {
return metric.getDescription();
}
return method.getName();
}
else {
ManagedOperation mo = this.attributeSource.getManagedOperation(method);
ManagedOperation mo = obtainAttributeSource().getManagedOperation(method);
if (mo != null && StringUtils.hasText(mo.getDescription())) {
return mo.getDescription();
}
@@ -257,7 +263,7 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
*/
@Override
protected MBeanParameterInfo[] getOperationParameters(Method method, String beanKey) {
ManagedOperationParameter[] params = this.attributeSource.getManagedOperationParameters(method);
ManagedOperationParameter[] params = obtainAttributeSource().getManagedOperationParameters(method);
if (ObjectUtils.isEmpty(params)) {
return super.getOperationParameters(method, beanKey);
}
@@ -279,7 +285,7 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
@Override
protected ModelMBeanNotificationInfo[] getNotificationInfo(Object managedBean, String beanKey) {
ManagedNotification[] notificationAttributes =
this.attributeSource.getManagedNotifications(getClassToExpose(managedBean));
obtainAttributeSource().getManagedNotifications(getClassToExpose(managedBean));
ModelMBeanNotificationInfo[] notificationInfos =
new ModelMBeanNotificationInfo[notificationAttributes.length];
@@ -299,7 +305,7 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
*/
@Override
protected void populateMBeanDescriptor(Descriptor desc, Object managedBean, String beanKey) {
ManagedResource mr = this.attributeSource.getManagedResource(getClassToExpose(managedBean));
ManagedResource mr = obtainAttributeSource().getManagedResource(getClassToExpose(managedBean));
if (mr == null) {
throw new InvalidMetadataException(
"No ManagedResource attribute found for class: " + getClassToExpose(managedBean));
@@ -337,15 +343,15 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
Descriptor desc, @Nullable Method getter, @Nullable Method setter, String beanKey) {
if (getter != null) {
ManagedMetric metric = this.attributeSource.getManagedMetric(getter);
ManagedMetric metric = obtainAttributeSource().getManagedMetric(getter);
if (metric != null) {
populateMetricDescriptor(desc, metric);
return;
}
}
ManagedAttribute gma = (getter != null ? this.attributeSource.getManagedAttribute(getter) : null);
ManagedAttribute sma = (setter != null ? this.attributeSource.getManagedAttribute(setter) : null);
ManagedAttribute gma = (getter != null ? obtainAttributeSource().getManagedAttribute(getter) : null);
ManagedAttribute sma = (setter != null ? obtainAttributeSource().getManagedAttribute(setter) : null);
populateAttributeDescriptor(desc,
(gma != null ? gma : ManagedAttribute.EMPTY),
(sma != null ? sma : ManagedAttribute.EMPTY));
@@ -399,7 +405,7 @@ public class MetadataMBeanInfoAssembler extends AbstractReflectiveMBeanInfoAssem
*/
@Override
protected void populateOperationDescriptor(Descriptor desc, Method method, String beanKey) {
ManagedOperation mo = this.attributeSource.getManagedOperation(method);
ManagedOperation mo = obtainAttributeSource().getManagedOperation(method);
if (mo != null) {
applyCurrencyTimeLimit(desc, mo.getCurrencyTimeLimit());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -57,8 +58,10 @@ import org.springframework.util.StringUtils;
*/
public class MethodExclusionMBeanInfoAssembler extends AbstractConfigurableMBeanInfoAssembler {
@Nullable
private Set<String> ignoredMethods;
@Nullable
private Map<String, Set<String>> ignoredMethodMappings;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils;
/**
@@ -57,11 +58,13 @@ public class MethodNameBasedMBeanInfoAssembler extends AbstractConfigurableMBean
/**
* Stores the set of method names to use for creating the management interface.
*/
@Nullable
private Set<String> managedMethods;
/**
* Stores the mappings of bean keys to an array of method names.
*/
@Nullable
private Map<String, Set<String>> methodMappings;

View File

@@ -61,6 +61,7 @@ public class KeyNamingStrategy implements ObjectNamingStrategy, InitializingBean
/**
* Stores the mappings of bean key to {@code ObjectName}.
*/
@Nullable
private Properties mappings;
/**
@@ -68,12 +69,14 @@ public class KeyNamingStrategy implements ObjectNamingStrategy, InitializingBean
* into the final merged set of {@code Properties} used for {@code ObjectName}
* resolution.
*/
@Nullable
private Resource[] mappingLocations;
/**
* Stores the result of merging the {@code mappings} {@code Properties}
* with the properties stored in the resources defined by {@code mappingLocations}.
*/
@Nullable
private Properties mergedMappings;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.jmx.export.metadata.JmxAttributeSource;
import org.springframework.jmx.export.metadata.ManagedResource;
import org.springframework.jmx.support.ObjectNameManager;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
@@ -51,8 +52,10 @@ public class MetadataNamingStrategy implements ObjectNamingStrategy, Initializin
/**
* The {@code JmxAttributeSource} implementation to use for reading metadata.
*/
@Nullable
private JmxAttributeSource attributeSource;
@Nullable
private String defaultDomain;
@@ -107,7 +110,8 @@ public class MetadataNamingStrategy implements ObjectNamingStrategy, Initializin
* with the managed resource's {@code Class}.
*/
@Override
public ObjectName getObjectName(Object managedBean, String beanKey) throws MalformedObjectNameException {
public ObjectName getObjectName(Object managedBean, @Nullable String beanKey) throws MalformedObjectNameException {
Assert.state(this.attributeSource != null, "No JmxAttributeSource set");
Class<?> managedClass = AopUtils.getTargetClass(managedBean);
ManagedResource mr = this.attributeSource.getManagedResource(managedClass);
@@ -116,6 +120,7 @@ public class MetadataNamingStrategy implements ObjectNamingStrategy, Initializin
return ObjectNameManager.getInstance(mr.getObjectName());
}
else {
Assert.state(beanKey != null, "No ManagedResource attribute and no bean key specified");
try {
return ObjectNameManager.getInstance(beanKey);
}

View File

@@ -64,14 +64,17 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport
private Map<String, Object> environment = new HashMap<>();
@Nullable
private MBeanServerForwarder forwarder;
@Nullable
private ObjectName objectName;
private boolean threaded = false;
private boolean daemon = false;
@Nullable
private JMXConnectorServer connectorServer;
@@ -224,11 +227,13 @@ public class ConnectorServerFactoryBean extends MBeanRegistrationSupport
*/
@Override
public void destroy() throws IOException {
if (logger.isInfoEnabled()) {
logger.info("Stopping JMX connector server: " + this.connectorServer);
}
try {
this.connectorServer.stop();
if (this.connectorServer != null) {
if (logger.isInfoEnabled()) {
logger.info("Stopping JMX connector server: " + this.connectorServer);
}
this.connectorServer.stop();
}
}
finally {
unregisterBeans();

View File

@@ -28,6 +28,7 @@ import javax.management.ObjectName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -75,6 +76,7 @@ public class MBeanRegistrationSupport {
/**
* The {@code MBeanServer} instance being used to register beans.
*/
@Nullable
protected MBeanServer server;
/**
@@ -101,6 +103,7 @@ public class MBeanRegistrationSupport {
/**
* Return the {@code MBeanServer} that the beans will be registered with.
*/
@Nullable
public final MBeanServer getServer() {
return this.server;
}
@@ -125,6 +128,7 @@ public class MBeanRegistrationSupport {
* @throws JMException if the registration failed
*/
protected void doRegister(Object mbean, ObjectName objectName) throws JMException {
Assert.state(this.server != null, "No MBeanServer set");
ObjectName actualObjectName;
synchronized (this.registeredBeans) {
@@ -188,6 +192,7 @@ public class MBeanRegistrationSupport {
* @param objectName the suggested ObjectName for the MBean
*/
protected void doUnregister(ObjectName objectName) {
Assert.state(this.server != null, "No MBeanServer set");
boolean actuallyUnregistered = false;
synchronized (this.registeredBeans) {

View File

@@ -34,6 +34,7 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
@@ -53,18 +54,23 @@ import org.springframework.util.CollectionUtils;
public class MBeanServerConnectionFactoryBean
implements FactoryBean<MBeanServerConnection>, BeanClassLoaderAware, InitializingBean, DisposableBean {
@Nullable
private JMXServiceURL serviceUrl;
private Map<String, Object> environment = new HashMap<>();
private boolean connectOnStartup = true;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
@Nullable
private JMXConnector connector;
@Nullable
private MBeanServerConnection connection;
@Nullable
private JMXConnectorLazyInitTargetSource connectorTargetSource;
@@ -131,6 +137,7 @@ public class MBeanServerConnectionFactoryBean
* environment properties.
*/
private void connect() throws IOException {
Assert.state(this.serviceUrl != null, "No JMXServiceURL set");
this.connector = JMXConnectorFactory.connect(this.serviceUrl, this.environment);
this.connection = this.connector.getMBeanServerConnection();
}
@@ -170,7 +177,8 @@ public class MBeanServerConnectionFactoryBean
*/
@Override
public void destroy() throws IOException {
if (this.connectorTargetSource == null || this.connectorTargetSource.isInitialized()) {
if (this.connector != null &&
(this.connectorTargetSource == null || this.connectorTargetSource.isInitialized())) {
this.connector.close();
}
}
@@ -186,6 +194,7 @@ public class MBeanServerConnectionFactoryBean
@Override
protected Object createObject() throws Exception {
Assert.state(serviceUrl != null, "No JMXServiceURL set");
return JMXConnectorFactory.connect(serviceUrl, environment);
}
@@ -203,6 +212,7 @@ public class MBeanServerConnectionFactoryBean
@Override
protected Object createObject() throws Exception {
Assert.state(connector != null, "JMXConnector not initialized");
return connector.getMBeanServerConnection();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,12 +58,15 @@ public class MBeanServerFactoryBean implements FactoryBean<MBeanServer>, Initial
private boolean locateExistingServerIfPossible = false;
@Nullable
private String agentId;
@Nullable
private String defaultDomain;
private boolean registerWithFactory = true;
@Nullable
private MBeanServer server;
private boolean newlyRegistered = false;

View File

@@ -41,12 +41,16 @@ import org.springframework.util.ObjectUtils;
*/
public class NotificationListenerHolder {
@Nullable
private NotificationListener notificationListener;
@Nullable
private NotificationFilter notificationFilter;
@Nullable
private Object handback;
@Nullable
protected Set<Object> mappedObjectNames;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,6 +23,7 @@ import javax.management.MBeanServer;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jmx.MBeanServerNotFoundException;
import org.springframework.lang.Nullable;
/**
* {@link FactoryBean} that obtains a WebSphere {@link javax.management.MBeanServer}
@@ -52,6 +53,7 @@ public class WebSphereMBeanServerFactoryBean implements FactoryBean<MBeanServer>
private static final String GET_MBEAN_SERVER_METHOD = "getMBeanServer";
@Nullable
private MBeanServer mbeanServer;

View File

@@ -33,6 +33,8 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
@@ -70,6 +72,7 @@ import org.springframework.util.ClassUtils;
public class JndiObjectFactoryBean extends JndiObjectLocator
implements FactoryBean<Object>, BeanFactoryAware, BeanClassLoaderAware {
@Nullable
private Class<?>[] proxyInterfaces;
private boolean lookupOnStartup = true;
@@ -78,12 +81,16 @@ public class JndiObjectFactoryBean extends JndiObjectLocator
private boolean exposeAccessContext = false;
@Nullable
private Object defaultObject;
@Nullable
private ConfigurableBeanFactory beanFactory;
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
@Nullable
private Object jndiObject;
@@ -310,7 +317,9 @@ public class JndiObjectFactoryBean extends JndiObjectLocator
// Create a JndiObjectTargetSource that mirrors the JndiObjectFactoryBean's configuration.
JndiObjectTargetSource targetSource = new JndiObjectTargetSource();
targetSource.setJndiTemplate(jof.getJndiTemplate());
targetSource.setJndiName(jof.getJndiName());
String jndiName = jof.getJndiName();
Assert.state(jndiName != null, "No JNDI name specified");
targetSource.setJndiName(jndiName);
targetSource.setExpectedType(jof.getExpectedType());
targetSource.setResourceRef(jof.isResourceRef());
targetSource.setLookupOnStartup(jof.lookupOnStartup);

View File

@@ -20,6 +20,7 @@ import javax.naming.NamingException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
@@ -48,8 +49,10 @@ import org.springframework.util.StringUtils;
*/
public abstract class JndiObjectLocator extends JndiLocatorSupport implements InitializingBean {
@Nullable
private String jndiName;
@Nullable
private Class<?> expectedType;
@@ -66,6 +69,7 @@ public abstract class JndiObjectLocator extends JndiLocatorSupport implements In
/**
* Return the JNDI name to look up.
*/
@Nullable
public String getJndiName() {
return this.jndiName;
}
@@ -105,7 +109,9 @@ public abstract class JndiObjectLocator extends JndiLocatorSupport implements In
* @see #lookup(String, Class)
*/
protected Object lookup() throws NamingException {
return lookup(getJndiName(), getExpectedType());
String jndiName = getJndiName();
Assert.state(jndiName != null, "No JNDI name specified");
return lookup(jndiName, getExpectedType());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ package org.springframework.jndi;
import javax.naming.NamingException;
import org.springframework.aop.TargetSource;
import org.springframework.lang.Nullable;
/**
* AOP {@link org.springframework.aop.TargetSource} that provides
@@ -64,8 +65,10 @@ public class JndiObjectTargetSource extends JndiObjectLocator implements TargetS
private boolean cache = true;
@Nullable
private Object cachedObject;
@Nullable
private Class<?> targetClass;

View File

@@ -43,6 +43,7 @@ public class JndiTemplate {
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private Properties environment;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@ 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;
/**
@@ -39,10 +40,13 @@ import org.springframework.util.CollectionUtils;
@Configuration
public abstract class AbstractAsyncConfiguration implements ImportAware {
@Nullable
protected AnnotationAttributes enableAsync;
@Nullable
protected Executor executor;
@Nullable
protected AsyncUncaughtExceptionHandler exceptionHandler;

View File

@@ -152,7 +152,6 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B
* @param asyncAnnotationTypes the async annotation types to introspect
* @return the applicable Pointcut object, or {@code null} if none
*/
@Nullable
protected Pointcut buildPointcut(Set<Class<? extends Annotation>> asyncAnnotationTypes) {
ComposablePointcut result = null;
for (Class<? extends Annotation> asyncAnnotationType : asyncAnnotationTypes) {
@@ -166,7 +165,7 @@ public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements B
}
result = result.union(mpc);
}
return result;
return (result != null ? result : Pointcut.TRUE);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import org.springframework.aop.framework.autoproxy.AbstractBeanFactoryAwareAdvis
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.task.TaskExecutor;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -74,10 +75,13 @@ public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAd
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private Class<? extends Annotation> asyncAnnotationType;
@Nullable
private Executor executor;
@Nullable
private AsyncUncaughtExceptionHandler exceptionHandler;

View File

@@ -47,8 +47,10 @@ import org.springframework.util.concurrent.SuccessCallback;
*/
public class AsyncResult<V> implements ListenableFuture<V> {
@Nullable
private final V value;
@Nullable
private final Throwable executionException;
@@ -86,6 +88,7 @@ public class AsyncResult<V> implements ListenableFuture<V> {
}
@Override
@Nullable
public V get() throws ExecutionException {
if (this.executionException != null) {
throw (this.executionException instanceof ExecutionException ?
@@ -96,6 +99,7 @@ public class AsyncResult<V> implements ListenableFuture<V> {
}
@Override
@Nullable
public V get(long timeout, TimeUnit unit) throws ExecutionException {
return get();
}

View File

@@ -53,6 +53,7 @@ import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.MethodIntrospector;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.config.CronTask;
@@ -107,14 +108,19 @@ public class ScheduledAnnotationBeanPostProcessor
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private Object scheduler;
@Nullable
private StringValueResolver embeddedValueResolver;
@Nullable
private String beanName;
@Nullable
private BeanFactory beanFactory;
@Nullable
private ApplicationContext applicationContext;
private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();
@@ -216,12 +222,12 @@ public class ScheduledAnnotationBeanPostProcessor
Assert.state(this.beanFactory != null, "BeanFactory must be set to find scheduler by type");
try {
// Search for TaskScheduler bean...
this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, false));
this.registrar.setTaskScheduler(resolveSchedulerBean(beanFactory, TaskScheduler.class, false));
}
catch (NoUniqueBeanDefinitionException ex) {
logger.debug("Could not find unique TaskScheduler bean", ex);
try {
this.registrar.setTaskScheduler(resolveSchedulerBean(TaskScheduler.class, true));
this.registrar.setTaskScheduler(resolveSchedulerBean(beanFactory, TaskScheduler.class, true));
}
catch (NoSuchBeanDefinitionException ex2) {
if (logger.isInfoEnabled()) {
@@ -237,12 +243,12 @@ public class ScheduledAnnotationBeanPostProcessor
logger.debug("Could not find default TaskScheduler bean", ex);
// Search for ScheduledExecutorService bean next...
try {
this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, false));
this.registrar.setScheduler(resolveSchedulerBean(beanFactory, ScheduledExecutorService.class, false));
}
catch (NoUniqueBeanDefinitionException ex2) {
logger.debug("Could not find unique ScheduledExecutorService bean", ex2);
try {
this.registrar.setScheduler(resolveSchedulerBean(ScheduledExecutorService.class, true));
this.registrar.setScheduler(resolveSchedulerBean(beanFactory, ScheduledExecutorService.class, true));
}
catch (NoSuchBeanDefinitionException ex3) {
if (logger.isInfoEnabled()) {
@@ -265,25 +271,24 @@ public class ScheduledAnnotationBeanPostProcessor
this.registrar.afterPropertiesSet();
}
private <T> T resolveSchedulerBean(Class<T> schedulerType, boolean byName) {
private <T> T resolveSchedulerBean(BeanFactory beanFactory, Class<T> schedulerType, boolean byName) {
if (byName) {
T scheduler = this.beanFactory.getBean(DEFAULT_TASK_SCHEDULER_BEAN_NAME, schedulerType);
if (this.beanFactory instanceof ConfigurableBeanFactory) {
T scheduler = beanFactory.getBean(DEFAULT_TASK_SCHEDULER_BEAN_NAME, schedulerType);
if (this.beanName != null && this.beanFactory instanceof ConfigurableBeanFactory) {
((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(
DEFAULT_TASK_SCHEDULER_BEAN_NAME, this.beanName);
}
return scheduler;
}
else if (this.beanFactory instanceof AutowireCapableBeanFactory) {
NamedBeanHolder<T> holder = ((AutowireCapableBeanFactory) this.beanFactory).resolveNamedBean(schedulerType);
if (this.beanFactory instanceof ConfigurableBeanFactory) {
((ConfigurableBeanFactory) this.beanFactory).registerDependentBean(
holder.getBeanName(), this.beanName);
else if (beanFactory instanceof AutowireCapableBeanFactory) {
NamedBeanHolder<T> holder = ((AutowireCapableBeanFactory) beanFactory).resolveNamedBean(schedulerType);
if (this.beanName != null && beanFactory instanceof ConfigurableBeanFactory) {
((ConfigurableBeanFactory) beanFactory).registerDependentBean(holder.getBeanName(), this.beanName);
}
return holder.getBeanInstance();
}
else {
return this.beanFactory.getBean(schedulerType);
return beanFactory.getBean(schedulerType);
}
}

View File

@@ -63,6 +63,7 @@ import org.springframework.util.concurrent.ListenableFuture;
*/
public class ConcurrentTaskExecutor implements AsyncListenableTaskExecutor, SchedulingTaskExecutor {
@Nullable
private static Class<?> managedExecutorServiceClass;
static {

View File

@@ -65,6 +65,7 @@ import org.springframework.util.ErrorHandler;
*/
public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements TaskScheduler {
@Nullable
private static Class<?> managedScheduledExecutorServiceClass;
static {
@@ -79,10 +80,12 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
}
}
private ScheduledExecutorService scheduledExecutor;
private boolean enterpriseConcurrentScheduler = false;
@Nullable
private ErrorHandler errorHandler;
@@ -93,7 +96,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
*/
public ConcurrentTaskScheduler() {
super();
setScheduledExecutor(null);
this.scheduledExecutor = initScheduledExecutor(null);
}
/**
@@ -108,7 +111,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
*/
public ConcurrentTaskScheduler(ScheduledExecutorService scheduledExecutor) {
super(scheduledExecutor);
setScheduledExecutor(scheduledExecutor);
this.scheduledExecutor = initScheduledExecutor(scheduledExecutor);
}
/**
@@ -124,10 +127,23 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
*/
public ConcurrentTaskScheduler(Executor concurrentExecutor, ScheduledExecutorService scheduledExecutor) {
super(concurrentExecutor);
setScheduledExecutor(scheduledExecutor);
this.scheduledExecutor = initScheduledExecutor(scheduledExecutor);
}
private ScheduledExecutorService initScheduledExecutor(@Nullable ScheduledExecutorService scheduledExecutor) {
if (scheduledExecutor != null) {
this.scheduledExecutor = scheduledExecutor;
this.enterpriseConcurrentScheduler = (managedScheduledExecutorServiceClass != null &&
managedScheduledExecutorServiceClass.isInstance(scheduledExecutor));
}
else {
this.scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
this.enterpriseConcurrentScheduler = false;
}
return this.scheduledExecutor;
}
/**
* Specify the {@link java.util.concurrent.ScheduledExecutorService} to delegate to.
* <p>Autodetects a JSR-236 {@link javax.enterprise.concurrent.ManagedScheduledExecutorService}
@@ -139,16 +155,8 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
* as well, pass the same executor reference to {@link #setConcurrentExecutor}.
* @see #setConcurrentExecutor
*/
public final void setScheduledExecutor(@Nullable ScheduledExecutorService scheduledExecutor) {
if (scheduledExecutor != null) {
this.scheduledExecutor = scheduledExecutor;
this.enterpriseConcurrentScheduler = (managedScheduledExecutorServiceClass != null &&
managedScheduledExecutorServiceClass.isInstance(scheduledExecutor));
}
else {
this.scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
this.enterpriseConcurrentScheduler = false;
}
public void setScheduledExecutor(@Nullable ScheduledExecutorService scheduledExecutor) {
initScheduledExecutor(scheduledExecutor);
}
/**
@@ -167,7 +175,8 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
return new EnterpriseConcurrentTriggerScheduler().schedule(decorateTask(task, true), trigger);
}
else {
ErrorHandler errorHandler = (this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true));
ErrorHandler errorHandler =
(this.errorHandler != null ? this.errorHandler : TaskUtils.getDefaultErrorHandler(true));
return new ReschedulingRunnable(task, trigger, this.scheduledExecutor, errorHandler).schedule();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jndi.JndiLocatorDelegate;
import org.springframework.jndi.JndiTemplate;
import org.springframework.lang.Nullable;
/**
* JNDI-based variant of {@link CustomizableThreadFactory}, performing a default lookup
@@ -51,8 +52,10 @@ public class DefaultManagedAwareThreadFactory extends CustomizableThreadFactory
private JndiLocatorDelegate jndiLocator = new JndiLocatorDelegate();
@Nullable
private String jndiName = "java:comp/DefaultManagedThreadFactory";
@Nullable
private ThreadFactory threadFactory;

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