Browse Source

Polishing

pull/25592/head
Juergen Hoeller 6 years ago
parent
commit
01ec5d83e6
  1. 81
      spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java
  2. 11
      spring-context/src/main/java/org/springframework/context/annotation/Configuration.java
  3. 56
      spring-context/src/main/java/org/springframework/context/annotation/PropertySource.java
  4. 4
      spring-core/src/main/java/org/springframework/core/io/support/PropertySourceFactory.java
  5. 19
      spring-core/src/main/java/org/springframework/util/ClassUtils.java
  6. 5
      spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java

81
spring-aop/src/main/java/org/springframework/aop/framework/ProxyFactoryBean.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2020 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,9 +21,7 @@ import java.io.ObjectInputStream; @@ -21,9 +21,7 @@ import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.Interceptor;
@ -334,11 +332,8 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -334,11 +332,8 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
// an independent instance of the configuration.
// In this case, no proxy will have an instance of this object's configuration,
// but will have an independent copy.
if (logger.isTraceEnabled()) {
logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
}
ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
// The copy needs a fresh advisor chain, and a fresh TargetSource.
TargetSource targetSource = freshTargetSource();
copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());
@ -349,9 +344,6 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -349,9 +344,6 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
}
copy.setFrozen(this.freezeProxy);
if (logger.isTraceEnabled()) {
logger.trace("Using ProxyCreatorSupport copy: " + copy);
}
return getProxy(copy.createAopProxy());
}
@ -438,16 +430,12 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -438,16 +430,12 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
// Materialize interceptor chain from bean names.
for (String name : this.interceptorNames) {
if (logger.isTraceEnabled()) {
logger.trace("Configuring advisor or advice '" + name + "'");
}
if (name.endsWith(GLOBAL_SUFFIX)) {
if (!(this.beanFactory instanceof ListableBeanFactory)) {
throw new AopConfigException(
"Can only use global advisors or interceptors with a ListableBeanFactory");
}
addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
addGlobalAdvisors((ListableBeanFactory) this.beanFactory,
name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
}
@ -464,7 +452,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -464,7 +452,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
// Avoid unnecessary creation of prototype bean just for advisor chain initialization.
advice = new PrototypePlaceholderAdvisor(name);
}
addAdvisorOnChainCreation(advice, name);
addAdvisorOnChainCreation(advice);
}
}
}
@ -487,11 +475,10 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -487,11 +475,10 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
if (logger.isDebugEnabled()) {
logger.debug("Refreshing bean named '" + pa.getBeanName() + "'");
}
// Replace the placeholder with a fresh prototype instance resulting
// from a getBean() lookup
// Replace the placeholder with a fresh prototype instance resulting from a getBean lookup
if (this.beanFactory == null) {
throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
"- cannot resolve prototype advisor '" + pa.getBeanName() + "'");
throw new IllegalStateException("No BeanFactory available anymore (probably due to " +
"serialization) - cannot resolve prototype advisor '" + pa.getBeanName() + "'");
}
Object bean = this.beanFactory.getBean(pa.getBeanName());
Advisor refreshedAdvisor = namedBeanToAdvisor(bean);
@ -508,28 +495,26 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -508,28 +495,26 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
/**
* Add all global interceptors and pointcuts.
*/
private void addGlobalAdvisor(ListableBeanFactory beanFactory, String prefix) {
private void addGlobalAdvisors(ListableBeanFactory beanFactory, String prefix) {
String[] globalAdvisorNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Advisor.class);
String[] globalInterceptorNames =
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Interceptor.class);
List<Object> beans = new ArrayList<Object>(globalAdvisorNames.length + globalInterceptorNames.length);
Map<Object, String> names = new HashMap<Object, String>(beans.size());
for (String name : globalAdvisorNames) {
Object bean = beanFactory.getBean(name);
beans.add(bean);
names.put(bean, name);
}
for (String name : globalInterceptorNames) {
Object bean = beanFactory.getBean(name);
beans.add(bean);
names.put(bean, name);
}
AnnotationAwareOrderComparator.sort(beans);
for (Object bean : beans) {
String name = names.get(bean);
if (name.startsWith(prefix)) {
addAdvisorOnChainCreation(bean, name);
if (globalAdvisorNames.length > 0 || globalInterceptorNames.length > 0) {
List<Object> beans = new ArrayList<Object>(globalAdvisorNames.length + globalInterceptorNames.length);
for (String name : globalAdvisorNames) {
if (name.startsWith(prefix)) {
beans.add(beanFactory.getBean(name));
}
}
for (String name : globalInterceptorNames) {
if (name.startsWith(prefix)) {
beans.add(beanFactory.getBean(name));
}
}
AnnotationAwareOrderComparator.sort(beans);
for (Object bean : beans) {
addAdvisorOnChainCreation(bean);
}
}
}
@ -540,17 +525,11 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -540,17 +525,11 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
* Because of these three possibilities, we can't type the signature
* more strongly.
* @param next advice, advisor or target object
* @param name bean name from which we obtained this object in our owning
* bean factory
*/
private void addAdvisorOnChainCreation(Object next, String name) {
private void addAdvisorOnChainCreation(Object next) {
// We need to convert to an Advisor if necessary so that our source reference
// matches what we find from superclass interceptors.
Advisor advisor = namedBeanToAdvisor(next);
if (logger.isTraceEnabled()) {
logger.trace("Adding advisor with name '" + name + "'");
}
addAdvisor(advisor);
addAdvisor(namedBeanToAdvisor(next));
}
/**
@ -561,9 +540,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -561,9 +540,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
*/
private TargetSource freshTargetSource() {
if (this.targetName == null) {
if (logger.isTraceEnabled()) {
logger.trace("Not refreshing target: Bean name not specified in 'interceptorNames'.");
}
// Not refreshing target: bean name not specified in 'interceptorNames'
return this.targetSource;
}
else {
@ -591,8 +568,8 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -591,8 +568,8 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
// We expected this to be an Advisor or Advice,
// but it wasn't. This is a configuration error.
throw new AopConfigException("Unknown advisor type " + next.getClass() +
"; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," +
"which may also be target or TargetSource", ex);
"; can only include Advisor or Advice type beans in interceptorNames chain " +
"except for last entry which may also be target instance or TargetSource", ex);
}
}
@ -603,7 +580,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport @@ -603,7 +580,7 @@ public class ProxyFactoryBean extends ProxyCreatorSupport
protected void adviceChanged() {
super.adviceChanged();
if (this.singleton) {
logger.debug("Advice has changed; recaching singleton instance");
logger.debug("Advice has changed; re-caching singleton instance");
synchronized (this) {
this.singletonInstance = null;
}

11
spring-context/src/main/java/org/springframework/context/annotation/Configuration.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@ -343,15 +343,16 @@ import org.springframework.stereotype.Component; @@ -343,15 +343,16 @@ import org.springframework.stereotype.Component;
*
* <p>By default, {@code @Bean} methods will be <em>eagerly instantiated</em> at container
* bootstrap time. To avoid this, {@code @Configuration} may be used in conjunction with
* the {@link Lazy @Lazy} annotation to indicate that all {@code @Bean} methods declared within
* the class are by default lazily initialized. Note that {@code @Lazy} may be used on
* individual {@code @Bean} methods as well.
* the {@link Lazy @Lazy} annotation to indicate that all {@code @Bean} methods declared
* within the class are by default lazily initialized. Note that {@code @Lazy} may be used
* on individual {@code @Bean} methods as well.
*
* <h2>Testing support for {@code @Configuration} classes</h2>
*
* <p>The Spring <em>TestContext framework</em> available in the {@code spring-test} module
* provides the {@code @ContextConfiguration} annotation which can accept an array of
* {@code @Configuration} {@code Class} objects:
* <em>component class</em> references &mdash; typically {@code @Configuration} or
* {@code @Component} classes.
*
* <pre class="code">
* &#064;RunWith(SpringRunner.class)

56
spring-context/src/main/java/org/springframework/context/annotation/PropertySource.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -54,25 +54,30 @@ import org.springframework.core.io.support.PropertySourceFactory; @@ -54,25 +54,30 @@ import org.springframework.core.io.support.PropertySourceFactory;
* }
* }</pre>
*
* Notice that the {@code Environment} object is
* <p>Notice that the {@code Environment} object is
* {@link org.springframework.beans.factory.annotation.Autowired @Autowired} into the
* configuration class and then used when populating the {@code TestBean} object. Given
* the configuration above, a call to {@code testBean.getName()} will return "myTestBean".
*
* <h3>Resolving ${...} placeholders in {@code <bean>} and {@code @Value} annotations</h3>
*
* In order to resolve ${...} placeholders in {@code <bean>} definitions or {@code @Value}
* annotations using properties from a {@code PropertySource}, one must register
* a {@code PropertySourcesPlaceholderConfigurer}. This happens automatically when using
* {@code <context:property-placeholder>} in XML, but must be explicitly registered using
* a {@code static} {@code @Bean} method when using {@code @Configuration} classes. See
* the "Working with externalized values" section of @{@link Configuration}'s javadoc and
* "a note on BeanFactoryPostProcessor-returning @Bean methods" of @{@link Bean}'s javadoc
* for details and examples.
* <h3>Resolving <code>${...}</code> placeholders in {@code <bean>} and {@code @Value} annotations</h3>
*
* <p>In order to resolve ${...} placeholders in {@code <bean>} definitions or {@code @Value}
* annotations using properties from a {@code PropertySource}, you must ensure that an
* appropriate <em>embedded value resolver</em> is registered in the {@code BeanFactory}
* used by the {@code ApplicationContext}. This happens automatically when using
* {@code <context:property-placeholder>} in XML. When using {@code @Configuration} classes
* this can be achieved by explicitly registering a {@code PropertySourcesPlaceholderConfigurer}
* via a {@code static} {@code @Bean} method. Note, however, that explicit registration
* of a {@code PropertySourcesPlaceholderConfigurer} via a {@code static} {@code @Bean}
* method is typically only required if you need to customize configuration such as the
* placeholder syntax, etc. See the "Working with externalized values" section of
* {@link Configuration @Configuration}'s javadocs and "a note on
* BeanFactoryPostProcessor-returning {@code @Bean} methods" of {@link Bean @Bean}'s
* javadocs for details and examples.
*
* <h3>Resolving ${...} placeholders within {@code @PropertySource} resource locations</h3>
*
* Any ${...} placeholders present in a {@code @PropertySource} {@linkplain #value()
* <p>Any ${...} placeholders present in a {@code @PropertySource} {@linkplain #value()
* resource location} will be resolved against the set of property sources already
* registered against the environment. For example:
*
@ -92,7 +97,7 @@ import org.springframework.core.io.support.PropertySourceFactory; @@ -92,7 +97,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
* }
* }</pre>
*
* Assuming that "my.placeholder" is present in one of the property sources already
* <p>Assuming that "my.placeholder" is present in one of the property sources already
* registered, e.g. system properties or environment variables, the placeholder will
* be resolved to the corresponding value. If not, then "default/path" will be used as a
* default. Expressing a default value (delimited by colon ":") is optional. If no
@ -101,10 +106,10 @@ import org.springframework.core.io.support.PropertySourceFactory; @@ -101,10 +106,10 @@ import org.springframework.core.io.support.PropertySourceFactory;
*
* <h3>A note on property overriding with @PropertySource</h3>
*
* In cases where a given property key exists in more than one {@code .properties}
* <p>In cases where a given property key exists in more than one {@code .properties}
* file, the last {@code @PropertySource} annotation processed will 'win' and override.
*
* For example, given two properties files {@code a.properties} and
* <p>For example, given two properties files {@code a.properties} and
* {@code b.properties}, consider the following two configuration classes
* that reference them with {@code @PropertySource} annotations:
*
@ -118,7 +123,7 @@ import org.springframework.core.io.support.PropertySourceFactory; @@ -118,7 +123,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
* public class ConfigB { }
* </pre>
*
* The override ordering depends on the order in which these classes are registered
* <p>The override ordering depends on the order in which these classes are registered
* with the application context.
*
* <pre class="code">
@ -128,12 +133,12 @@ import org.springframework.core.io.support.PropertySourceFactory; @@ -128,12 +133,12 @@ import org.springframework.core.io.support.PropertySourceFactory;
* ctx.refresh();
* </pre>
*
* In the scenario above, the properties in {@code b.properties} will override any
* <p>In the scenario above, the properties in {@code b.properties} will override any
* duplicates that exist in {@code a.properties}, because {@code ConfigB} was registered
* last.
*
* <p>In certain situations, it may not be possible or practical to tightly control
* property source ordering when using {@code @ProperySource} annotations. For example,
* property source ordering when using {@code @PropertySource} annotations. For example,
* if the {@code @Configuration} classes above were registered via component-scanning,
* the ordering is difficult to predict. In such cases - and if overriding is important -
* it is recommended that the user fall back to using the programmatic PropertySource API.
@ -150,6 +155,7 @@ import org.springframework.core.io.support.PropertySourceFactory; @@ -150,6 +155,7 @@ import org.springframework.core.io.support.PropertySourceFactory;
* @author Chris Beams
* @author Juergen Hoeller
* @author Phillip Webb
* @author Sam Brannen
* @since 3.1
* @see PropertySources
* @see Configuration
@ -164,8 +170,11 @@ import org.springframework.core.io.support.PropertySourceFactory; @@ -164,8 +170,11 @@ import org.springframework.core.io.support.PropertySourceFactory;
public @interface PropertySource {
/**
* Indicate the name of this property source. If omitted, a name will
* be generated based on the description of the underlying resource.
* Indicate the name of this property source. If omitted, the {@link #factory()}
* will generate a name based on the underlying resource (in the case of
* {@link org.springframework.core.io.support.DefaultPropertySourceFactory}:
* derived from the resource description through a corresponding name-less
* {@link org.springframework.core.io.support.ResourcePropertySource} constructor).
* @see org.springframework.core.env.PropertySource#getName()
* @see org.springframework.core.io.Resource#getDescription()
*/
@ -173,8 +182,9 @@ public @interface PropertySource { @@ -173,8 +182,9 @@ public @interface PropertySource {
/**
* Indicate the resource location(s) of the properties file to be loaded.
* For example, {@code "classpath:/com/myco/app.properties"} or
* {@code "file:/path/to/file"}.
* <p>Both traditional and XML-based properties file formats are supported
* &mdash; for example, {@code "classpath:/com/myco/app.properties"}
* or {@code "file:/path/to/file.xml"}.
* <p>Resource location wildcards (e.g. *&#42;/*.properties) are not permitted;
* each location must evaluate to exactly one {@code .properties} resource.
* <p>${...} placeholders will be resolved against any/all property sources already

4
spring-core/src/main/java/org/springframework/core/io/support/PropertySourceFactory.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2020 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,8 @@ public interface PropertySourceFactory { @@ -32,6 +32,8 @@ public interface PropertySourceFactory {
/**
* Create a {@link PropertySource} that wraps the given resource.
* @param name the name of the property source
* (can be {@code null} in which case the factory implementation
* will have to generate a name based on the given resource)
* @param resource the resource (potentially encoded) to wrap
* @return the new {@link PropertySource} (never {@code null})
* @throws IOException if resource resolution failed

19
spring-core/src/main/java/org/springframework/util/ClassUtils.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@ -206,7 +206,7 @@ public abstract class ClassUtils { @@ -206,7 +206,7 @@ public abstract class ClassUtils {
* @param name the name of the Class
* @param classLoader the class loader to use
* (may be {@code null}, which indicates the default class loader)
* @return Class instance for the supplied name
* @return a class instance for the supplied name
* @throws ClassNotFoundException if the class was not found
* @throws LinkageError if the class file could not be loaded
* @see Class#forName(String, boolean, ClassLoader)
@ -275,7 +275,7 @@ public abstract class ClassUtils { @@ -275,7 +275,7 @@ public abstract class ClassUtils {
* @param className the name of the Class
* @param classLoader the class loader to use
* (may be {@code null}, which indicates the default class loader)
* @return Class instance for the supplied name
* @return a class instance for the supplied name
* @throws IllegalArgumentException if the class name was not resolvable
* (that is, the class could not be found or the class file could not be loaded)
* @see #forName(String, ClassLoader)
@ -459,7 +459,7 @@ public abstract class ClassUtils { @@ -459,7 +459,7 @@ public abstract class ClassUtils {
* @param lhsType the target type
* @param rhsType the value type that should be assigned to the target type
* @return if the target type is assignable from the value type
* @see TypeUtils#isAssignable
* @see TypeUtils#isAssignable(java.lang.reflect.Type, java.lang.reflect.Type)
*/
public static boolean isAssignable(Class<?> lhsType, Class<?> rhsType) {
Assert.notNull(lhsType, "Left-hand side type must not be null");
@ -469,17 +469,12 @@ public abstract class ClassUtils { @@ -469,17 +469,12 @@ public abstract class ClassUtils {
}
if (lhsType.isPrimitive()) {
Class<?> resolvedPrimitive = primitiveWrapperTypeMap.get(rhsType);
if (lhsType == resolvedPrimitive) {
return true;
}
return (lhsType == resolvedPrimitive);
}
else {
Class<?> resolvedWrapper = primitiveTypeToWrapperMap.get(rhsType);
if (resolvedWrapper != null && lhsType.isAssignableFrom(resolvedWrapper)) {
return true;
}
return (resolvedWrapper != null && lhsType.isAssignableFrom(resolvedWrapper));
}
return false;
}
/**
@ -990,7 +985,7 @@ public abstract class ClassUtils { @@ -990,7 +985,7 @@ public abstract class ClassUtils {
* @param clazz the clazz to analyze
* @param paramTypes the parameter types of the method
* @return whether the class has a corresponding constructor
* @see Class#getMethod
* @see Class#getConstructor
*/
public static boolean hasConstructor(Class<?> clazz, Class<?>... paramTypes) {
return (getConstructorIfAvailable(clazz, paramTypes) != null);

5
spring-jdbc/src/main/java/org/springframework/jdbc/datasource/DataSourceTransactionManager.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2020 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.
@ -126,7 +126,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan @@ -126,7 +126,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
/**
* Create a new DataSourceTransactionManager instance.
* @param dataSource JDBC DataSource to manage transactions for
* @param dataSource the JDBC DataSource to manage transactions for
*/
public DataSourceTransactionManager(DataSource dataSource) {
this();
@ -134,6 +134,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan @@ -134,6 +134,7 @@ public class DataSourceTransactionManager extends AbstractPlatformTransactionMan
afterPropertiesSet();
}
/**
* Set the JDBC DataSource that this instance should manage transactions for.
* <p>This will typically be a locally defined DataSource, for example an

Loading…
Cancel
Save