Flexible constructor resolution in AutowireCapableBeanFactory.createBean(Class)
Closes gh-29855 See gh-29823
This commit is contained in:
parent
94fc24b6fb
commit
0e8838db90
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2019 the original author or authors.
|
* Copyright 2002-2023 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.
|
||||||
|
@ -130,6 +130,8 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
|
||||||
* {@link BeanPostProcessor BeanPostProcessors}.
|
* {@link BeanPostProcessor BeanPostProcessors}.
|
||||||
* <p>Note: This is intended for creating a fresh instance, populating annotated
|
* <p>Note: This is intended for creating a fresh instance, populating annotated
|
||||||
* fields and methods as well as applying all standard bean initialization callbacks.
|
* fields and methods as well as applying all standard bean initialization callbacks.
|
||||||
|
* Constructor resolution is done via {@link #AUTOWIRE_CONSTRUCTOR}, also influenced
|
||||||
|
* by {@link SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors}.
|
||||||
* It does <i>not</i> imply traditional by-name or by-type autowiring of properties;
|
* It does <i>not</i> imply traditional by-name or by-type autowiring of properties;
|
||||||
* use {@link #createBean(Class, int, boolean)} for those purposes.
|
* use {@link #createBean(Class, int, boolean)} for those purposes.
|
||||||
* @param beanClass the class of the bean to create
|
* @param beanClass the class of the bean to create
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2022 the original author or authors.
|
* Copyright 2002-2023 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.
|
||||||
|
@ -314,8 +314,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T> T createBean(Class<T> beanClass) throws BeansException {
|
public <T> T createBean(Class<T> beanClass) throws BeansException {
|
||||||
// Use prototype bean definition, to avoid registering bean as dependent bean.
|
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
|
||||||
RootBeanDefinition bd = new RootBeanDefinition(beanClass);
|
RootBeanDefinition bd = new RootBeanDefinition(beanClass);
|
||||||
|
bd.setAutowireMode(AUTOWIRE_CONSTRUCTOR);
|
||||||
bd.setScope(SCOPE_PROTOTYPE);
|
bd.setScope(SCOPE_PROTOTYPE);
|
||||||
bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
|
bd.allowCaching = ClassUtils.isCacheSafe(beanClass, getBeanClassLoader());
|
||||||
return (T) createBean(beanClass.getName(), bd, null);
|
return (T) createBean(beanClass.getName(), bd, null);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2018 the original author or authors.
|
* Copyright 2002-2023 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.
|
||||||
|
@ -22,7 +22,6 @@ import org.quartz.spi.TriggerFiredBundle;
|
||||||
import org.springframework.beans.BeanWrapper;
|
import org.springframework.beans.BeanWrapper;
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
import org.springframework.beans.PropertyAccessorFactory;
|
import org.springframework.beans.PropertyAccessorFactory;
|
||||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
@ -88,7 +87,7 @@ public class SpringBeanJobFactory extends AdaptableJobFactory
|
||||||
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
|
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
|
||||||
Object job = (this.applicationContext != null ?
|
Object job = (this.applicationContext != null ?
|
||||||
this.applicationContext.getAutowireCapableBeanFactory().createBean(
|
this.applicationContext.getAutowireCapableBeanFactory().createBean(
|
||||||
bundle.getJobDetail().getJobClass(), AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false) :
|
bundle.getJobDetail().getJobClass()) :
|
||||||
super.createJobInstance(bundle));
|
super.createJobInstance(bundle));
|
||||||
|
|
||||||
if (isEligibleForPropertyPopulation(job)) {
|
if (isEligibleForPropertyPopulation(job)) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2021 the original author or authors.
|
* Copyright 2002-2023 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.
|
||||||
|
@ -144,7 +144,7 @@ public final class SpringBeanContainer implements BeanContainer {
|
||||||
try {
|
try {
|
||||||
if (lifecycleOptions.useJpaCompliantCreation()) {
|
if (lifecycleOptions.useJpaCompliantCreation()) {
|
||||||
return new SpringContainedBean<>(
|
return new SpringContainedBean<>(
|
||||||
this.beanFactory.createBean(beanType, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false),
|
this.beanFactory.createBean(beanType),
|
||||||
this.beanFactory::destroyBean);
|
this.beanFactory::destroyBean);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2023 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.
|
||||||
|
@ -36,7 +36,6 @@ 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
|
||||||
|
@ -174,8 +173,7 @@ public class RequestScopeTests {
|
||||||
assertThat(beanProvider.getIfAvailable()).isNull();
|
assertThat(beanProvider.getIfAvailable()).isNull();
|
||||||
assertThat(beanProvider.getIfUnique()).isNull();
|
assertThat(beanProvider.getIfUnique()).isNull();
|
||||||
|
|
||||||
ObjectProvider<CountingTestBean> provider =
|
ObjectProvider<CountingTestBean> provider = this.beanFactory.createBean(ProviderBean.class).provider;
|
||||||
((ProviderBean) this.beanFactory.createBean(ProviderBean.class, AUTOWIRE_CONSTRUCTOR, false)).provider;
|
|
||||||
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(provider::getObject);
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(provider::getObject);
|
||||||
assertThat(provider.getIfAvailable()).isNull();
|
assertThat(provider.getIfAvailable()).isNull();
|
||||||
assertThat(provider.getIfUnique()).isNull();
|
assertThat(provider.getIfUnique()).isNull();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2020 the original author or authors.
|
* Copyright 2002-2023 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.
|
||||||
|
@ -36,7 +36,6 @@ 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 Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
@ -209,13 +208,12 @@ public class RequestScopedProxyTests {
|
||||||
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(
|
||||||
() -> this.beanFactory.getBean(CountingTestBean.class).absquatulate());
|
() -> this.beanFactory.getBean(CountingTestBean.class).absquatulate());
|
||||||
|
|
||||||
final ObjectProvider<CountingTestBean> beanProvider = this.beanFactory.getBeanProvider(CountingTestBean.class);
|
ObjectProvider<CountingTestBean> beanProvider = this.beanFactory.getBeanProvider(CountingTestBean.class);
|
||||||
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(() -> beanProvider.getObject().absquatulate());
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(() -> beanProvider.getObject().absquatulate());
|
||||||
beanProvider.ifAvailable(TestBean::absquatulate);
|
beanProvider.ifAvailable(TestBean::absquatulate);
|
||||||
beanProvider.ifUnique(TestBean::absquatulate);
|
beanProvider.ifUnique(TestBean::absquatulate);
|
||||||
|
|
||||||
final ObjectProvider<CountingTestBean> provider =
|
ObjectProvider<CountingTestBean> provider = this.beanFactory.createBean(ProviderBean.class).provider;
|
||||||
((ProviderBean) this.beanFactory.createBean(ProviderBean.class, AUTOWIRE_CONSTRUCTOR, false)).provider;
|
|
||||||
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(() -> provider.getObject().absquatulate());
|
assertThatExceptionOfType(ScopeNotActiveException.class).isThrownBy(() -> provider.getObject().absquatulate());
|
||||||
provider.ifAvailable(TestBean::absquatulate);
|
provider.ifAvailable(TestBean::absquatulate);
|
||||||
provider.ifUnique(TestBean::absquatulate);
|
provider.ifUnique(TestBean::absquatulate);
|
||||||
|
|
Loading…
Reference in New Issue