Skip to content
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

@Primary annotation is not working for beans with the same name [SPR-13980] #18552

Closed
spring-projects-issues opened this issue Feb 25, 2016 · 3 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: declined A suggestion or change that we don't feel we should currently apply

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Feb 25, 2016

Modestas Kažinauskas opened SPR-13980 and commented

@Primary annotation is not working for beans. This issue persists in older spring versions too.

Please see my code below

@Configuration
public class ConfigA {
    @Bean
    @Primary
    public MyObject createMyObject() {
        return new MyObject("A");
    }
}
@Configuration
public class ConfigB {
    @Bean
    public MyObject createMyObject() {
        return new MyObject("B");
    }
}
public class MyObject {
    private String name;

    public MyObject(String name) {
        this.name = name;
    }
    ...
}
@Configuration
public class Runner {
    @Autowired
    private MyObject myObject;

    @PostConstruct
    void init() {
        System.out.println(myObject.getName()); //Output is B, but primary bean is A
    }
}

2016-02-25 08:39:49.351 INFO 1196 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'init' with a different definition: replacing
[Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=true; factoryBeanName=configA; factoryMethodName=createMyObject; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/modzo/ConfigA.class]]
with
[Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=configB; factoryMethodName=createMyObject; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/modzo/ConfigB.class]]

DefaultListableBeanFactory takes bean name as 'init'. and overrides with another.

This configuration is resolved by changing init method name to not duplicate.


Affects: 4.2.4

Reference URL: #15434

Issue Links:

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

I'm afraid this is working as designed: If you choose the same factory method name (which is usually a meaning bean name such as "accountService", not a generic name like "init"), we assume you intend to override a previously registered bean of the same name... including all of its metadata.

@Primary does not have an effect on this overriding-by-name behavior, since it is only meant to be applied for injection point resolution: i.e. when multiple matching beans have been found in the bean definition registry but only one is to be selected for a particular injection point. This is conceptually very different from overriding bean definitions which leads to hard replacing in the registry, with the previously registered bean not available anymore.

Juergen

@spring-projects-issues
Copy link
Collaborator Author

Modestas Kažinauskas commented

Hi,
thanks for your great explanation.

Could you please specify the link to documentation or design document? It would be very helpful.

Thanks!

@spring-projects-issues
Copy link
Collaborator Author

Modestas Kažinauskas commented

I have changed 'init' to 'createMyObject'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

2 participants