java – 如何依赖注入依赖注入在Spring @Bean方法参数中工作

我理解Spring DI以及它的工作原理.

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

例如,在以下示例中,方法fernas1和fernas2参数在运行时被擦除.但是,spring仍然可以将正确的Abbas bean实例注入其中.

@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的相同问题和解决方案都适用于方法和构造函数参数.

最佳答案
如果参数名称反射不可用,它将使用类文件本身中的信息.见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 – 如何依赖注入依赖注入在Spring @Bean方法参数中工作 - 代码日志