How the injection dependency by name works in the parameters of the Spring @Bean method

I understand Spring DI and how it works in general.

But what I can’t understand here is if the method parameter is entered @Bean, how does Spring know the parameter name so that it can insert beans from its bean factory based on the parameter name?

For example, in the following example, the parameters of the method fernas1and are fernas2erased at run time. however, Spring can still inject the correct Abbasbean instance into it .

@SpringBootApplication
public class DemoApplication {

    @Autowired
    private Abbas abbas1;    // this is understandable, hence the field name is available at runtime

    @Autowired
    private Abbas abbas2;   // this is understandable, hence the field name is available at runtime

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(DemoApplication.class, args);

        Map<String, Fernas> beansOfType = ctx.getBeansOfType(Fernas.class);
        System.out.println(beansOfType);

        Arrays.stream(DemoApplication.class.getMethods())
                .filter(m -> m.getName().startsWith("fernas"))
                .flatMap(m -> Stream.of(m.getParameters()))
                .map(Parameter::getName)
                .forEach(System.out::println);

        System.out.println(ctx.getBean(DemoApplication.class).abbas1);
        System.out.println(ctx.getBean(DemoApplication.class).abbas2);
    }

    class Abbas {
        String name;

        @Override
        public String toString() {
            return name;
        }
    }

    class Fernas {
        Abbas abbas;

        @Override
        public String toString() {
            return abbas.toString();
        }
    }

    @Bean
    public Abbas abbas1() {
        Abbas abbas = new Abbas();
        abbas.name = "abbas1";
        return abbas;
    }

    @Bean
    public Abbas abbas2() {
        Abbas abbas = new Abbas();
        abbas.name = "abbas2";
        return abbas;
    }

    // this is not understandable, hence the parameter name is NOT available at runtime
    @Bean
    public Fernas fernas1(Abbas abbas1) {
        Fernas fernas1 = new Fernas();
        fernas1.abbas = abbas1;
        return fernas1;
    }

    // this is not understandable, hence the parameter name is NOT available at runtime
    @Bean
    public Fernas fernas2(Abbas abbas2) {
        Fernas fernas2 = new Fernas();
        fernas2.abbas = abbas2;
        return fernas2;
    }
}

The EDIT: . A similar problem and solution from @Javier works on methodand parameters constructor.

+6
source share
1 answer

, . . DefaultParameterNameDiscoverer

ParameterNameDiscoverer , Java 8 ( ) ASM-based LocalVariableTableParameterNameDiscoverer .

, LocalVariableTable DemoApplication.fernas2

    Start  Length  Slot  Name   Signature
        0      16     0  this   Lcom/example/demo/DemoApplication;
        0      16     1 abbas2   Lcom/example/demo/DemoApplication$Abbas;
        9       7     2 fernas2   Lcom/example/demo/DemoApplication$Fernas;
+4

All Articles