Merge branch '5.2.x'
This commit is contained in:
commit
9999414b3b
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2020 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -41,12 +41,11 @@ import java.lang.annotation.Target;
|
||||||
* regular constructors: i.e. lookup methods cannot get replaced on beans returned
|
* regular constructors: i.e. lookup methods cannot get replaced on beans returned
|
||||||
* from factory methods where we cannot dynamically provide a subclass for them.
|
* from factory methods where we cannot dynamically provide a subclass for them.
|
||||||
*
|
*
|
||||||
* <p><b>Concrete limitations in typical Spring configuration scenarios:</b>
|
* <p><b>Recommendations for typical Spring configuration scenarios:</b>
|
||||||
* When used with component scanning or any other mechanism that filters out abstract
|
* When a concrete class may be needed in certain scenarios, consider providing stub
|
||||||
* beans, provide stub implementations of your lookup methods to be able to declare
|
* implementations of your lookup methods. And please remember that lookup methods
|
||||||
* them as concrete classes. And please remember that lookup methods won't work on
|
* won't work on beans returned from {@code @Bean} methods in configuration classes;
|
||||||
* beans returned from {@code @Bean} methods in configuration classes; you'll have
|
* you'll have to resort to {@code @Inject Provider<TargetBean>} or the like instead.
|
||||||
* to resort to {@code @Inject Provider<TargetBean>} or the like instead.
|
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -41,8 +41,13 @@ import org.springframework.util.StringUtils;
|
||||||
* {@link org.springframework.beans.factory.config.BeanExpressionResolver}
|
* {@link org.springframework.beans.factory.config.BeanExpressionResolver}
|
||||||
* interface, parsing and evaluating Spring EL using Spring's expression module.
|
* interface, parsing and evaluating Spring EL using Spring's expression module.
|
||||||
*
|
*
|
||||||
|
* <p>All beans in the containing {@code BeanFactory} are made available as
|
||||||
|
* predefined variables with their common bean name, including standard context
|
||||||
|
* beans such as "environment", "systemProperties" and "systemEnvironment".
|
||||||
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
|
* @see BeanExpressionContext#getBeanFactory()
|
||||||
* @see org.springframework.expression.ExpressionParser
|
* @see org.springframework.expression.ExpressionParser
|
||||||
* @see org.springframework.expression.spel.standard.SpelExpressionParser
|
* @see org.springframework.expression.spel.standard.SpelExpressionParser
|
||||||
* @see org.springframework.expression.spel.support.StandardEvaluationContext
|
* @see org.springframework.expression.spel.support.StandardEvaluationContext
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -72,10 +72,7 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||||
|
|
||||||
/** Bean factory for this context. */
|
/** Bean factory for this context. */
|
||||||
@Nullable
|
@Nullable
|
||||||
private DefaultListableBeanFactory beanFactory;
|
private volatile DefaultListableBeanFactory beanFactory;
|
||||||
|
|
||||||
/** Synchronization monitor for the internal BeanFactory. */
|
|
||||||
private final Object beanFactoryMonitor = new Object();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -131,10 +128,8 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||||
beanFactory.setSerializationId(getId());
|
beanFactory.setSerializationId(getId());
|
||||||
customizeBeanFactory(beanFactory);
|
customizeBeanFactory(beanFactory);
|
||||||
loadBeanDefinitions(beanFactory);
|
loadBeanDefinitions(beanFactory);
|
||||||
synchronized (this.beanFactoryMonitor) {
|
|
||||||
this.beanFactory = beanFactory;
|
this.beanFactory = beanFactory;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (IOException ex) {
|
catch (IOException ex) {
|
||||||
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
|
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
|
||||||
}
|
}
|
||||||
|
@ -142,43 +137,38 @@ public abstract class AbstractRefreshableApplicationContext extends AbstractAppl
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void cancelRefresh(BeansException ex) {
|
protected void cancelRefresh(BeansException ex) {
|
||||||
synchronized (this.beanFactoryMonitor) {
|
DefaultListableBeanFactory beanFactory = this.beanFactory;
|
||||||
if (this.beanFactory != null) {
|
if (beanFactory != null) {
|
||||||
this.beanFactory.setSerializationId(null);
|
beanFactory.setSerializationId(null);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
super.cancelRefresh(ex);
|
super.cancelRefresh(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected final void closeBeanFactory() {
|
protected final void closeBeanFactory() {
|
||||||
synchronized (this.beanFactoryMonitor) {
|
DefaultListableBeanFactory beanFactory = this.beanFactory;
|
||||||
if (this.beanFactory != null) {
|
if (beanFactory != null) {
|
||||||
this.beanFactory.setSerializationId(null);
|
beanFactory.setSerializationId(null);
|
||||||
this.beanFactory = null;
|
this.beanFactory = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether this context currently holds a bean factory,
|
* Determine whether this context currently holds a bean factory,
|
||||||
* i.e. has been refreshed at least once and not been closed yet.
|
* i.e. has been refreshed at least once and not been closed yet.
|
||||||
*/
|
*/
|
||||||
protected final boolean hasBeanFactory() {
|
protected final boolean hasBeanFactory() {
|
||||||
synchronized (this.beanFactoryMonitor) {
|
|
||||||
return (this.beanFactory != null);
|
return (this.beanFactory != null);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final ConfigurableListableBeanFactory getBeanFactory() {
|
public final ConfigurableListableBeanFactory getBeanFactory() {
|
||||||
synchronized (this.beanFactoryMonitor) {
|
DefaultListableBeanFactory beanFactory = this.beanFactory;
|
||||||
if (this.beanFactory == null) {
|
if (beanFactory == null) {
|
||||||
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
|
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
|
||||||
"call 'refresh' before accessing beans via the ApplicationContext");
|
"call 'refresh' before accessing beans via the ApplicationContext");
|
||||||
}
|
}
|
||||||
return this.beanFactory;
|
return beanFactory;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -87,17 +87,20 @@ public abstract class AbstractMessageChannel implements MessageChannel, Intercep
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setInterceptors(List<ChannelInterceptor> interceptors) {
|
public void setInterceptors(List<ChannelInterceptor> interceptors) {
|
||||||
|
Assert.noNullElements(interceptors, "'interceptors' must not contain null elements");
|
||||||
this.interceptors.clear();
|
this.interceptors.clear();
|
||||||
this.interceptors.addAll(interceptors);
|
this.interceptors.addAll(interceptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInterceptor(ChannelInterceptor interceptor) {
|
public void addInterceptor(ChannelInterceptor interceptor) {
|
||||||
|
Assert.notNull(interceptor, "'interceptor' must not be null");
|
||||||
this.interceptors.add(interceptor);
|
this.interceptors.add(interceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addInterceptor(int index, ChannelInterceptor interceptor) {
|
public void addInterceptor(int index, ChannelInterceptor interceptor) {
|
||||||
|
Assert.notNull(interceptor, "'interceptor' must not be null");
|
||||||
this.interceptors.add(index, interceptor);
|
this.interceptors.add(index, interceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -24,6 +24,7 @@ import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||||
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
|
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,6 +58,7 @@ public abstract class InterceptingHttpAccessor extends HttpAccessor {
|
||||||
* @see AnnotationAwareOrderComparator
|
* @see AnnotationAwareOrderComparator
|
||||||
*/
|
*/
|
||||||
public void setInterceptors(List<ClientHttpRequestInterceptor> interceptors) {
|
public void setInterceptors(List<ClientHttpRequestInterceptor> interceptors) {
|
||||||
|
Assert.noNullElements(interceptors, "'interceptors' must not contain null elements");
|
||||||
// Take getInterceptors() List as-is when passed in here
|
// Take getInterceptors() List as-is when passed in here
|
||||||
if (this.interceptors != interceptors) {
|
if (this.interceptors != interceptors) {
|
||||||
this.interceptors.clear();
|
this.interceptors.clear();
|
||||||
|
|
|
@ -539,8 +539,12 @@ example shows:
|
||||||
</bean>
|
</bean>
|
||||||
----
|
----
|
||||||
|
|
||||||
The `systemProperties` variable is predefined, so you can use it in your expressions, as
|
All beans in the application context are available as predefined variables with their
|
||||||
the following example shows:
|
common bean name. This includes standard context beans such as `environment` (of type
|
||||||
|
`org.springframework.core.env.Environment`) as well as `systemProperties` and
|
||||||
|
`systemEnvironment` (of type `Map<String, Object>`) for access to the runtime environment.
|
||||||
|
|
||||||
|
The following example shows access to the `systemProperties` bean as a SpEL variable:
|
||||||
|
|
||||||
[source,xml,indent=0,subs="verbatim"]
|
[source,xml,indent=0,subs="verbatim"]
|
||||||
----
|
----
|
||||||
|
@ -551,8 +555,7 @@ the following example shows:
|
||||||
</bean>
|
</bean>
|
||||||
----
|
----
|
||||||
|
|
||||||
Note that you do not have to prefix the predefined variable with the `#`
|
Note that you do not have to prefix the predefined variable with the `#` symbol here.
|
||||||
symbol in this context.
|
|
||||||
|
|
||||||
You can also refer to other bean properties by name, as the following example shows:
|
You can also refer to other bean properties by name, as the following example shows:
|
||||||
|
|
||||||
|
@ -576,8 +579,8 @@ You can also refer to other bean properties by name, as the following example sh
|
||||||
[[expressions-beandef-annotation-based]]
|
[[expressions-beandef-annotation-based]]
|
||||||
=== Annotation Configuration
|
=== Annotation Configuration
|
||||||
|
|
||||||
To specify a default value, you can place the `@Value` annotation on fields, methods, and method or constructor
|
To specify a default value, you can place the `@Value` annotation on fields, methods,
|
||||||
parameters.
|
and method or constructor parameters.
|
||||||
|
|
||||||
The following example sets the default value of a field variable:
|
The following example sets the default value of a field variable:
|
||||||
|
|
||||||
|
@ -1675,7 +1678,7 @@ The following example shows how to use the Elvis operator:
|
||||||
----
|
----
|
||||||
ExpressionParser parser = new SpelExpressionParser();
|
ExpressionParser parser = new SpelExpressionParser();
|
||||||
|
|
||||||
String name = parser.parseExpression("name?:'Unknown'").getValue(String.class);
|
String name = parser.parseExpression("name?:'Unknown'").getValue(new Inventor(), String.class);
|
||||||
System.out.println(name); // 'Unknown'
|
System.out.println(name); // 'Unknown'
|
||||||
----
|
----
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
|
@ -1683,7 +1686,7 @@ The following example shows how to use the Elvis operator:
|
||||||
----
|
----
|
||||||
val parser = SpelExpressionParser()
|
val parser = SpelExpressionParser()
|
||||||
|
|
||||||
val name = parser.parseExpression("name?:'Unknown'").getValue(String::class.java)
|
val name = parser.parseExpression("name?:'Unknown'").getValue(Inventor(), String::class.java)
|
||||||
println(name) // 'Unknown'
|
println(name) // 'Unknown'
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue