Ignore resolved bean from non-active scope in getIfAvailable/getIfUnique
Closes gh-24822
This commit is contained in:
@@ -350,6 +350,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
String scopeName = mbd.getScope();
|
String scopeName = mbd.getScope();
|
||||||
|
if (!StringUtils.hasLength(scopeName)) {
|
||||||
|
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
|
||||||
|
}
|
||||||
final Scope scope = this.scopes.get(scopeName);
|
final Scope scope = this.scopes.get(scopeName);
|
||||||
if (scope == null) {
|
if (scope == null) {
|
||||||
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
|
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
|
||||||
@@ -367,10 +370,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
|||||||
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
|
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
|
||||||
}
|
}
|
||||||
catch (IllegalStateException ex) {
|
catch (IllegalStateException ex) {
|
||||||
throw new BeanCreationException(beanName,
|
throw new ScopeNotActiveException(beanName, scopeName, ex);
|
||||||
"Scope '" + scopeName + "' is not active for the current thread; consider " +
|
|
||||||
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
|
|
||||||
ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -384,12 +384,48 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public T getIfAvailable() throws BeansException {
|
public T getIfAvailable() throws BeansException {
|
||||||
return resolveBean(requiredType, null, false);
|
try {
|
||||||
|
return resolveBean(requiredType, null, false);
|
||||||
|
}
|
||||||
|
catch (ScopeNotActiveException ex) {
|
||||||
|
// Ignore resolved bean in non-active scope
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void ifAvailable(Consumer<T> dependencyConsumer) throws BeansException {
|
||||||
|
T dependency = getIfAvailable();
|
||||||
|
if (dependency != null) {
|
||||||
|
try {
|
||||||
|
dependencyConsumer.accept(dependency);
|
||||||
|
}
|
||||||
|
catch (ScopeNotActiveException ex) {
|
||||||
|
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public T getIfUnique() throws BeansException {
|
public T getIfUnique() throws BeansException {
|
||||||
return resolveBean(requiredType, null, true);
|
try {
|
||||||
|
return resolveBean(requiredType, null, true);
|
||||||
|
}
|
||||||
|
catch (ScopeNotActiveException ex) {
|
||||||
|
// Ignore resolved bean in non-active scope
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void ifUnique(Consumer<T> dependencyConsumer) throws BeansException {
|
||||||
|
T dependency = getIfUnique();
|
||||||
|
if (dependency != null) {
|
||||||
|
try {
|
||||||
|
dependencyConsumer.accept(dependency);
|
||||||
|
}
|
||||||
|
catch (ScopeNotActiveException ex) {
|
||||||
|
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public Stream<T> stream() {
|
public Stream<T> stream() {
|
||||||
@@ -1925,17 +1961,36 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public Object getIfAvailable() throws BeansException {
|
public Object getIfAvailable() throws BeansException {
|
||||||
if (this.optional) {
|
try {
|
||||||
return createOptionalDependency(this.descriptor, this.beanName);
|
if (this.optional) {
|
||||||
|
return createOptionalDependency(this.descriptor, this.beanName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
|
||||||
|
@Override
|
||||||
|
public boolean isRequired() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
catch (ScopeNotActiveException ex) {
|
||||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
|
// Ignore resolved bean in non-active scope
|
||||||
@Override
|
return null;
|
||||||
public boolean isRequired() {
|
}
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
};
|
@Override
|
||||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
public void ifAvailable(Consumer<Object> dependencyConsumer) throws BeansException {
|
||||||
|
Object dependency = getIfAvailable();
|
||||||
|
if (dependency != null) {
|
||||||
|
try {
|
||||||
|
dependencyConsumer.accept(dependency);
|
||||||
|
}
|
||||||
|
catch (ScopeNotActiveException ex) {
|
||||||
|
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1953,11 +2008,30 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (this.optional) {
|
try {
|
||||||
return createOptionalDependency(descriptorToUse, this.beanName);
|
if (this.optional) {
|
||||||
|
return createOptionalDependency(descriptorToUse, this.beanName);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
catch (ScopeNotActiveException ex) {
|
||||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
// Ignore resolved bean in non-active scope
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ifUnique(Consumer<Object> dependencyConsumer) throws BeansException {
|
||||||
|
Object dependency = getIfUnique();
|
||||||
|
if (dependency != null) {
|
||||||
|
try {
|
||||||
|
dependencyConsumer.accept(dependency);
|
||||||
|
}
|
||||||
|
catch (ScopeNotActiveException ex) {
|
||||||
|
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.beans.factory.support;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A subclass of {@link BeanCreationException} which indicates that the target scope
|
||||||
|
* is not active, e.g. in case of request or session scope.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 5.3
|
||||||
|
* @see org.springframework.beans.factory.BeanFactory#getBean
|
||||||
|
* @see org.springframework.beans.factory.config.Scope
|
||||||
|
* @see AbstractBeanDefinition#setScope
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ScopeNotActiveException extends BeanCreationException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new ScopeNotActiveException.
|
||||||
|
* @param beanName the name of the bean requested
|
||||||
|
* @param scopeName the name of the target scope
|
||||||
|
* @param cause the root cause, typically from {@link org.springframework.beans.factory.config.Scope#get}
|
||||||
|
*/
|
||||||
|
public ScopeNotActiveException(String beanName, String scopeName, IllegalStateException cause) {
|
||||||
|
super(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " +
|
||||||
|
"defining a scoped proxy for this bean if you intend to refer to it from a singleton", cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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.
|
||||||
@@ -23,8 +23,11 @@ import org.junit.jupiter.api.Test;
|
|||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
|
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.support.ScopeNotActiveException;
|
||||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||||
|
import org.springframework.beans.testfixture.beans.CountingTestBean;
|
||||||
import org.springframework.beans.testfixture.beans.DerivedTestBean;
|
import org.springframework.beans.testfixture.beans.DerivedTestBean;
|
||||||
import org.springframework.beans.testfixture.beans.TestBean;
|
import org.springframework.beans.testfixture.beans.TestBean;
|
||||||
import org.springframework.context.expression.StandardBeanExpressionResolver;
|
import org.springframework.context.expression.StandardBeanExpressionResolver;
|
||||||
@@ -33,6 +36,7 @@ import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
|||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
import static org.springframework.beans.factory.config.AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Rob Harrop
|
* @author Rob Harrop
|
||||||
@@ -47,7 +51,7 @@ public class RequestScopeTests {
|
|||||||
|
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup() throws Exception {
|
public void setup() {
|
||||||
this.beanFactory.registerScope("request", new RequestScope());
|
this.beanFactory.registerScope("request", new RequestScope());
|
||||||
this.beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
|
this.beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
|
||||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.beanFactory);
|
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.beanFactory);
|
||||||
@@ -62,7 +66,7 @@ public class RequestScopeTests {
|
|||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getFromScope() throws Exception {
|
public void getFromScope() {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
request.setContextPath("/path");
|
request.setContextPath("/path");
|
||||||
RequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
RequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
||||||
@@ -77,7 +81,7 @@ public class RequestScopeTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void destructionAtRequestCompletion() throws Exception {
|
public void destructionAtRequestCompletion() {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
||||||
RequestContextHolder.setRequestAttributes(requestAttributes);
|
RequestContextHolder.setRequestAttributes(requestAttributes);
|
||||||
@@ -93,7 +97,7 @@ public class RequestScopeTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getFromFactoryBeanInScope() throws Exception {
|
public void getFromFactoryBeanInScope() {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
RequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
RequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
||||||
RequestContextHolder.setRequestAttributes(requestAttributes);
|
RequestContextHolder.setRequestAttributes(requestAttributes);
|
||||||
@@ -107,7 +111,7 @@ public class RequestScopeTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void circleLeadsToException() throws Exception {
|
public void circleLeadsToException() {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
RequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
RequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
||||||
RequestContextHolder.setRequestAttributes(requestAttributes);
|
RequestContextHolder.setRequestAttributes(requestAttributes);
|
||||||
@@ -143,7 +147,7 @@ public class RequestScopeTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void requestScopedInnerBeanDestroyedWhileContainedBySingleton() throws Exception {
|
public void requestScopedInnerBeanDestroyedWhileContainedBySingleton() {
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
ServletRequestAttributes requestAttributes = new ServletRequestAttributes(request);
|
||||||
RequestContextHolder.setRequestAttributes(requestAttributes);
|
RequestContextHolder.setRequestAttributes(requestAttributes);
|
||||||
@@ -160,4 +164,31 @@ public class RequestScopeTests {
|
|||||||
assertThat(outer1.wasDestroyed()).isFalse();
|
assertThat(outer1.wasDestroyed()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void scopeNotAvailable() {
|
||||||
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(
|
||||||
|
() -> this.beanFactory.getBean(CountingTestBean.class));
|
||||||
|
|
||||||
|
ObjectProvider<CountingTestBean> beanProvider = this.beanFactory.getBeanProvider(CountingTestBean.class);
|
||||||
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(beanProvider::getObject);
|
||||||
|
assertThat(beanProvider.getIfAvailable()).isNull();
|
||||||
|
assertThat(beanProvider.getIfUnique()).isNull();
|
||||||
|
|
||||||
|
ObjectProvider<CountingTestBean> provider =
|
||||||
|
((ProviderBean) this.beanFactory.createBean(ProviderBean.class, AUTOWIRE_CONSTRUCTOR, false)).provider;
|
||||||
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(provider::getObject);
|
||||||
|
assertThat(provider.getIfAvailable()).isNull();
|
||||||
|
assertThat(provider.getIfUnique()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class ProviderBean {
|
||||||
|
|
||||||
|
public ObjectProvider<CountingTestBean> provider;
|
||||||
|
|
||||||
|
public ProviderBean(ObjectProvider<CountingTestBean> provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -20,10 +20,13 @@ import org.junit.jupiter.api.BeforeEach;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import org.springframework.aop.support.AopUtils;
|
import org.springframework.aop.support.AopUtils;
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||||
|
import org.springframework.beans.factory.support.ScopeNotActiveException;
|
||||||
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
|
||||||
|
import org.springframework.beans.testfixture.beans.CountingTestBean;
|
||||||
import org.springframework.beans.testfixture.beans.DerivedTestBean;
|
import org.springframework.beans.testfixture.beans.DerivedTestBean;
|
||||||
import org.springframework.beans.testfixture.beans.ITestBean;
|
import org.springframework.beans.testfixture.beans.ITestBean;
|
||||||
import org.springframework.beans.testfixture.beans.TestBean;
|
import org.springframework.beans.testfixture.beans.TestBean;
|
||||||
@@ -32,6 +35,8 @@ import org.springframework.core.io.ClassPathResource;
|
|||||||
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
import static org.springframework.beans.factory.config.AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
@@ -51,7 +56,7 @@ public class RequestScopedProxyTests {
|
|||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetFromScope() throws Exception {
|
public void testGetFromScope() {
|
||||||
String name = "requestScopedObject";
|
String name = "requestScopedObject";
|
||||||
TestBean bean = (TestBean) this.beanFactory.getBean(name);
|
TestBean bean = (TestBean) this.beanFactory.getBean(name);
|
||||||
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
|
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
|
||||||
@@ -76,7 +81,7 @@ public class RequestScopedProxyTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetFromScopeThroughDynamicProxy() throws Exception {
|
public void testGetFromScopeThroughDynamicProxy() {
|
||||||
String name = "requestScopedProxy";
|
String name = "requestScopedProxy";
|
||||||
ITestBean bean = (ITestBean) this.beanFactory.getBean(name);
|
ITestBean bean = (ITestBean) this.beanFactory.getBean(name);
|
||||||
// assertTrue(AopUtils.isJdkDynamicProxy(bean));
|
// assertTrue(AopUtils.isJdkDynamicProxy(bean));
|
||||||
@@ -101,7 +106,7 @@ public class RequestScopedProxyTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDestructionAtRequestCompletion() throws Exception {
|
public void testDestructionAtRequestCompletion() {
|
||||||
String name = "requestScopedDisposableObject";
|
String name = "requestScopedDisposableObject";
|
||||||
DerivedTestBean bean = (DerivedTestBean) this.beanFactory.getBean(name);
|
DerivedTestBean bean = (DerivedTestBean) this.beanFactory.getBean(name);
|
||||||
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
|
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
|
||||||
@@ -127,7 +132,7 @@ public class RequestScopedProxyTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetFromFactoryBeanInScope() throws Exception {
|
public void testGetFromFactoryBeanInScope() {
|
||||||
String name = "requestScopedFactoryBean";
|
String name = "requestScopedFactoryBean";
|
||||||
TestBean bean = (TestBean) this.beanFactory.getBean(name);
|
TestBean bean = (TestBean) this.beanFactory.getBean(name);
|
||||||
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
|
assertThat(AopUtils.isCglibProxy(bean)).isTrue();
|
||||||
@@ -149,7 +154,7 @@ public class RequestScopedProxyTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetInnerBeanFromScope() throws Exception {
|
public void testGetInnerBeanFromScope() {
|
||||||
TestBean bean = (TestBean) this.beanFactory.getBean("outerBean");
|
TestBean bean = (TestBean) this.beanFactory.getBean("outerBean");
|
||||||
assertThat(AopUtils.isAopProxy(bean)).isFalse();
|
assertThat(AopUtils.isAopProxy(bean)).isFalse();
|
||||||
assertThat(AopUtils.isCglibProxy(bean.getSpouse())).isTrue();
|
assertThat(AopUtils.isCglibProxy(bean.getSpouse())).isTrue();
|
||||||
@@ -173,7 +178,7 @@ public class RequestScopedProxyTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetAnonymousInnerBeanFromScope() throws Exception {
|
public void testGetAnonymousInnerBeanFromScope() {
|
||||||
TestBean bean = (TestBean) this.beanFactory.getBean("outerBean");
|
TestBean bean = (TestBean) this.beanFactory.getBean("outerBean");
|
||||||
assertThat(AopUtils.isAopProxy(bean)).isFalse();
|
assertThat(AopUtils.isAopProxy(bean)).isFalse();
|
||||||
assertThat(AopUtils.isCglibProxy(bean.getSpouse())).isTrue();
|
assertThat(AopUtils.isCglibProxy(bean.getSpouse())).isTrue();
|
||||||
@@ -199,4 +204,31 @@ public class RequestScopedProxyTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void scopeNotAvailable() {
|
||||||
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(
|
||||||
|
() -> this.beanFactory.getBean(CountingTestBean.class).absquatulate());
|
||||||
|
|
||||||
|
final ObjectProvider<CountingTestBean> beanProvider = this.beanFactory.getBeanProvider(CountingTestBean.class);
|
||||||
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(() -> beanProvider.getObject().absquatulate());
|
||||||
|
beanProvider.ifAvailable(TestBean::absquatulate);
|
||||||
|
beanProvider.ifUnique(TestBean::absquatulate);
|
||||||
|
|
||||||
|
final ObjectProvider<CountingTestBean> provider =
|
||||||
|
((ProviderBean) this.beanFactory.createBean(ProviderBean.class, AUTOWIRE_CONSTRUCTOR, false)).provider;
|
||||||
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(() -> provider.getObject().absquatulate());
|
||||||
|
provider.ifAvailable(TestBean::absquatulate);
|
||||||
|
provider.ifUnique(TestBean::absquatulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class ProviderBean {
|
||||||
|
|
||||||
|
public ObjectProvider<CountingTestBean> provider;
|
||||||
|
|
||||||
|
public ProviderBean(ObjectProvider<CountingTestBean> provider) {
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
||||||
https://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
|
||||||
|
|
||||||
<bean id="requestScopedObject" class="org.springframework.beans.testfixture.beans.TestBean" scope="request">
|
<bean id="requestScopedObject" class="org.springframework.beans.testfixture.beans.TestBean" scope="request">
|
||||||
<property name="name" value="#{request.contextPath}"/>
|
<property name="name" value="#{request.contextPath}"/>
|
||||||
@@ -12,6 +11,8 @@
|
|||||||
|
|
||||||
<bean id="requestScopedFactoryBean" class="org.springframework.beans.testfixture.beans.factory.DummyFactory" scope="request"/>
|
<bean id="requestScopedFactoryBean" class="org.springframework.beans.testfixture.beans.factory.DummyFactory" scope="request"/>
|
||||||
|
|
||||||
|
<bean id="requestScopedUniqueBean" class="org.springframework.beans.testfixture.beans.CountingTestBean" scope="request"/>
|
||||||
|
|
||||||
<bean id="requestScopedObjectCircle1" class="org.springframework.beans.testfixture.beans.TestBean" scope="request">
|
<bean id="requestScopedObjectCircle1" class="org.springframework.beans.testfixture.beans.TestBean" scope="request">
|
||||||
<property name="spouse" ref="requestScopedObjectCircle2"/>
|
<property name="spouse" ref="requestScopedObjectCircle2"/>
|
||||||
</bean>
|
</bean>
|
||||||
@@ -20,22 +21,22 @@
|
|||||||
<property name="spouse" ref="requestScopedObjectCircle1"/>
|
<property name="spouse" ref="requestScopedObjectCircle1"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="requestScopedOuterBean" class="org.springframework.beans.testfixture.beans.DerivedTestBean" scope="request">
|
<bean id="requestScopedOuterBean" class="org.springframework.beans.testfixture.beans.DerivedTestBean" scope="request">
|
||||||
<property name="name" value="outer"/>
|
<property name="name" value="outer"/>
|
||||||
<property name="spouse">
|
<property name="spouse">
|
||||||
<bean class="org.springframework.beans.testfixture.beans.DerivedTestBean">
|
<bean class="org.springframework.beans.testfixture.beans.DerivedTestBean">
|
||||||
<property name="name" value="inner"/>
|
<property name="name" value="inner"/>
|
||||||
</bean>
|
</bean>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="singletonOuterBean" class="org.springframework.beans.testfixture.beans.DerivedTestBean" lazy-init="true">
|
<bean id="singletonOuterBean" class="org.springframework.beans.testfixture.beans.DerivedTestBean" lazy-init="true">
|
||||||
<property name="name" value="outer"/>
|
<property name="name" value="outer"/>
|
||||||
<property name="spouse">
|
<property name="spouse">
|
||||||
<bean class="org.springframework.beans.testfixture.beans.DerivedTestBean" scope="request">
|
<bean class="org.springframework.beans.testfixture.beans.DerivedTestBean" scope="request">
|
||||||
<property name="name" value="inner"/>
|
<property name="name" value="inner"/>
|
||||||
</bean>
|
</bean>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|||||||
@@ -24,6 +24,10 @@
|
|||||||
<aop:scoped-proxy/>
|
<aop:scoped-proxy/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="requestScopedUniqueBean" class="org.springframework.beans.testfixture.beans.CountingTestBean" scope="request">
|
||||||
|
<aop:scoped-proxy/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<bean id="requestScopedObjectCircle1" class="org.springframework.beans.testfixture.beans.TestBean" scope="request">
|
<bean id="requestScopedObjectCircle1" class="org.springframework.beans.testfixture.beans.TestBean" scope="request">
|
||||||
<aop:scoped-proxy/>
|
<aop:scoped-proxy/>
|
||||||
<property name="spouse" ref="requestScopedObjectCircle2"/>
|
<property name="spouse" ref="requestScopedObjectCircle2"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user