Skip to content

Allow type produced by ScopedProxyFactoryBean to be determined before singleton is created [SPR-14816] #19382

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Oct 17, 2016 · 1 comment
Assignees
Labels
type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Oct 17, 2016

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:

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.


Affects: 4.3.3

Reference URL: spring-projects/spring-boot#7150

Issue Links:

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants