gpt4 book ai didi

java - 名称依赖注入(inject)如何在 Spring @Bean 方法参数中工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:19:57 25 4
gpt4 key购买 nike

我了解 Spring DI 及其一般工作原理。

但我在这里无法理解的是在 @Bean 方法参数注入(inject)的情况下,spring 如何知道参数名称以便它可以根据参数名称从其 bean 工厂注入(inject) bean?

例如,在下面的示例中,方法 fernas1fernas2 参数在运行时被删除。但是,spring 仍然可以将正确的 Abbas bean 实例注入(inject)其中。

@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;
}
}

编辑:同样的问题和@Javier 的解决方案都适用于methodconstructor 参数。

最佳答案

如果参数名称反射不可用,它将使用类文件本身中的信息。参见 DefaultParameterNameDiscoverer

Default implementation of the ParameterNameDiscoverer strategy interface, using the Java 8 standard reflection mechanism (if available), and falling back to the ASM-based LocalVariableTableParameterNameDiscoverer for checking debug information in the class file.

例如DemoApplication.fernas2的LocalVariableTable是

    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;

关于java - 名称依赖注入(inject)如何在 Spring @Bean 方法参数中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48613997/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com