Java “春天是怎样的?”;“神奇地”;知道使用哪种Bean类型吗?
使用Spring5时,我很困惑Java “春天是怎样的?”;“神奇地”;知道使用哪种Bean类型吗?,java,spring,Java,Spring,使用Spring5时,我很困惑注释ConfigApplicationContext“神奇地”知道如何使用接口的正确实现,因为引用的是接口而不是实现类 插图 注意:已输入不相关的代码,如导入和不相关的行为 一个接口CleaningTool和两个实现类Broom和VacuumCleaner,在接口方法doCleanJob() 然后,我的AnnotationConfigApplicationContex使用我的类AppConfig,因此: @Configuration public class App
注释ConfigApplicationContext
“神奇地”知道如何使用接口的正确实现,因为引用的是接口而不是实现类
插图
注意:已输入不相关的代码,如导入和不相关的行为
一个接口CleaningTool
和两个实现类Broom
和VacuumCleaner
,在接口方法doCleanJob()
然后,我的AnnotationConfigApplicationContex
使用我的类AppConfig
,因此:
@Configuration
public class AppConfig {
@Bean
public CleaningTool broom(){
return new Broom();
}
@Bean
public CleaningTool vacuum(){
return new VacuumCleaner();
}
}
最后,在我的MainApp
类中,我调用了AnnotationConfigApplicationContext
的getBean()
方法,在这里我测试了这一令人费解的现象,起初我认为它不起作用:
public class MainApp {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
CleaningTool vacuum = ctx.getBean(VacuumCleaner.class);
vacuum.doCleanJob();
}
}
控制台输出:Zoom
即使我的AppConfig
和MainApp
中的引用类型都是CleaningTool
,Spring还是知道如何找到与类VacuumCleaner.class
匹配的Bean,从而使用了VacuumCleaner
的行为
这个“魔法”是如何工作的?
@Configuration
旨在提供一个工具来定义bean。
Spring创建这些bean(类的实例)并将它们存储在ApplicationContext中
您可以将应用程序上下文视为一个映射,其中包含实际bean的id/类到相应单例的实际实例之间的映射
因此,当spring启动时,它会创建Broom
和VacuumCleaner
,并将这两个bean放入应用程序上下文中
然后,应用程序上下文“就绪”,并调用以下行:
CleaningTool vacuum = ctx.getBean(VacuumCleaner.class);
请注意,您不需要接口
CleaningTool
,而是需要具体的类VacuumCleaner
。在本例中,spring转到其内部映射,并通过具体类检索值(实际对象)。这里没有魔法:)回答得很好!澄清一下我的困惑:事实上,应用程序上下文(在本例中)中带Bean注释的方法返回的是CleaningTool
接口,而不是一个具体的类-这可能是您可以解释的吗?非常感谢,实际上这并不重要,我们都喜欢“编程到接口而不是具体类型”,但在这种情况下,spring无论如何都会知道这些是bean。毕竟它调用了@Configuration
的这些方法,并得到了真正的对象。。。
@Configuration
public class AppConfig {
@Bean
public CleaningTool broom(){
return new Broom();
}
@Bean
public CleaningTool vacuum(){
return new VacuumCleaner();
}
}
public class MainApp {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
CleaningTool vacuum = ctx.getBean(VacuumCleaner.class);
vacuum.doCleanJob();
}
}
CleaningTool vacuum = ctx.getBean(VacuumCleaner.class);