鉴于参数名称在编译期间丢失,Spring如何通过参数名称自动装配?

Jar*_*lak 3 java reflection spring

考虑使用创建的两个相同类型的bean进行以下配置:

@Configuration
@ComponentScan(basePackageClasses = TwoStrings.class)
public class Config {

    @Bean
    public String one() {
        return "one";
    }

    @Bean
    public String two() {
        return "two";
    }

}
Run Code Online (Sandbox Code Playgroud)

依赖于上面两个bean的另一个bean是由组件扫描创建的:

@Component
public class TwoStrings {

    public final String a;
    public final String b;

    @Autowired
    public TwoStrings(String one, String two) {
        this.a = one;
        this.b = two;
    }

}
Run Code Online (Sandbox Code Playgroud)

编译期间局部变量/参数的名称将丢失,并且在运行时不可用:

在此输入图像描述

但是,Spring以某种方式String正确地自动连接两个bean.下面的示例测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Config.class )
public class Example {

    @Autowired
    private TwoStrings twoStrings;

    @Test
    public void test() {
        System.out.println(twoStrings.a);
        System.out.println(twoStrings.b);
    }

}
Run Code Online (Sandbox Code Playgroud)

版画

one
two
Run Code Online (Sandbox Code Playgroud)

鉴于构造函数参数的名称丢失,我希望Spring抛出异常,说有超过1个类型的bean String,但Spring以某种方式使用参数名称自动装配bean.

问题是Spring如何知道构造函数参数的名称?

bed*_*rin 6

Spring 在这种情况下使用调试信息 - 如果编译没有调试信息的代码,即使用javac-g:none标志,它将失败.

摘自文档:

请记住,为了使这项工作开箱即用,必须在启用调试标志的情况下编译代码,以便Spring可以从构造函数中查找参数名称.如果无法使用debug标志(或不想)编译代码,则可以使用@ConstructorProperties JDK批注显式命名构造函数参数.

Java 8引入了一种使用Reflection API读取此信息的方法,但是必须使用-parameters标志来编译类javac