Here is my case, I defined a default bean in xml configuration, sometimes I want override that bean with another implementation via @Component and @Primary, it's fine if injection is autowired by type but not name, the ideal solution is pinning the primary bean definition make it cannot be overridden by non-primary one.

Here is test case:

package test;

import static org.assertj.core.api.Assertions.assertThat;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

@SpringJUnitConfig
@ContextConfiguration(locations = "ctx.xml")
public class OverrideBeanTests {

    @Autowired
    private Service service;

    @Test
    void test() {
        assertThat(service).isInstanceOf(CustomService.class);
    }

}
package test;

public class Service {

}
package test;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Primary
@Component("service")
public class CustomService extends Service {

}

<?xml version="1.0" encoding="UTF-8"?>
<beans default-autowire="byName"
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    https://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    https://www.springframework.org/schema/context/spring-context.xsd">
    <context:component-scan base-package="test"/>
    <bean id="service" class="test.Service"/>
</beans>

Comment From: sbrannen

The appears to be related to:

  • 26241

Comment From: quaff

The appears to be related to:

That cannot handle autowiring by name usage, and multiple instances are created but only one is needed.

Comment From: snicoll

I understand that the behavior can be rather unintuitive but we've decided no to make further changes in that area. Actually, we're going to deprecate bean definition overriding wholesale, see #31288.

Comment From: quaff

I understand that the behavior can be rather unintuitive but we've decided no to make further changes in that area. Actually, we're going to deprecate bean definition overriding wholesale, see #31288.

It make sense that primary bean definition override non-primary one.