You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We have some code in Spring Boot that looks up beans using beanFactory.getBeanNamesForType(type, true, false);. It does so during application context refresh. It fails to find any scoped beans (in this specific case they're scoped due to Spring Cloud's @RefreshScope). If the call is made once refresh has completed, the scoped beans are found.
This simplified example should illustrate the described behaviour:
package com.example;
import java.util.Arrays;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
@SpringBootApplication
public class Gh7150Application {
@Autowired
private ApplicationContext applicationContext;
public static void main(String[] args) {
String[] names = SpringApplication.run(Gh7150Application.class, args).getBeanNamesForType(MyBean.class, true, false);
System.out.println("Names post refresh: " + Arrays.toString(names));
}
@PostConstruct
public void postConstruct() {
String[] names = this.applicationContext.getBeanNamesForType(MyBean.class, true, false);
System.out.println("Names in post construct: " + Arrays.toString(names));
}
@Bean
@Scope(scopeName="example", proxyMode=ScopedProxyMode.TARGET_CLASS)
public MyBean myBean() {
return new MyBean();
}
private static class MyBean {
}
}
Digging into it a bit, the problem appears to be that a singleton hasn't been created for the ScopedProxyFactoryBean and the bean definition contains insufficient information to determine the type of bean that will be produced. However, all of the information does appear to be available. Would it be possible to enhance the container such this information is used and the bean can be found before it's created?
I believe we need this enhancement to fix the referenced Spring Boot issue. If appropriate, a change in 4.3.x would be much appreciated.
I've refined our getBeanNamesForType algorithm to proceed with type determination even for a non-existing FactoryBean singleton, as long as there is a decorated definition. Our scoped proxy mechanism was setting such a decorated definition already, for bypassing the FactoryBean and checking the type of the target definition... but our getBeanNamesForType non-eager-init code path didn't take that into account yet.
Uh oh!
There was an error while loading. Please reload this page.
Andy Wilkinson opened SPR-14816 and commented
We have some code in Spring Boot that looks up beans using
beanFactory.getBeanNamesForType(type, true, false);
. It does so during application context refresh. It fails to find any scoped beans (in this specific case they're scoped due to Spring Cloud's@RefreshScope
). If the call is made once refresh has completed, the scoped beans are found.This simplified example should illustrate the described behaviour:
Digging into it a bit, the problem appears to be that a singleton hasn't been created for the
ScopedProxyFactoryBean
and the bean definition contains insufficient information to determine the type of bean that will be produced. However, all of the information does appear to be available. Would it be possible to enhance the container such this information is used and the bean can be found before it's created?I believe we need this enhancement to fix the referenced Spring Boot issue. If appropriate, a change in 4.3.x would be much appreciated.
Affects: 4.3.3
Reference URL: spring-projects/spring-boot#7150
Issue Links:
The text was updated successfully, but these errors were encountered: