按关键词阅读:
最近我看了看Springboot的源码 , 借着周末分享@Import这一小知识点 , 也正好体验一下CSDN博客最新的编辑器 。 编辑起来很好用 , 舒服 。
再看源码之前先写一个小的demo , 试着看看@Import是怎么用的 。 (为避免文章过长 , 下面代码均有一定程度的代码删减 , 可以自行补全或查看源码哦!)
1.创建一个maven项目 , pom.xml文件配置如下:
2.创建一个实体类
package com.entity; public class User implements Serializable{private String name; private String age;public User() {this.name = "xiaochen";this.age = "6"; }}
3.创建ImportUser类
package com.demo; public class ImportUser implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[] {"com.entity.User"}; }}
这里看到ImportSelector接口 , 是不是好像在哪里见过呢?
4.创建配置类
package com.demo; @Import(ImportUser.class)@Configurationpublic class ImportConfiguration {}
5.创建启动类
package com.demo;public class ImportDemo { public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();//这里使用register()和scan()方法都可,用scan()方法就不用在配置类中使用@Configuration注解了 。 //applicationContext.register(ImportConfiguration.class);applicationContext.scan("com.demo");applicationContext.refresh();User user = applicationContext.getBean(User.class);System.out.println(user); }}
6 , 运行结果
文章插图
上边的代码很简单 , 就不过多解释 , 下面直接看Springboot中是怎么使用的 。
我们知道@SpringbootApplication注解主要是由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan组成 。 而@EnableAutoConfiguration中就用到了@Import注解 , 用于引入
EnableAutoConfigurationImportSelector类 , 代码如下:
@Import(EnableAutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {}
这里我们先创建一个Springboot启动类
@SpringBootApplicationpublic class ApplicationStart { public static void main(String[] args) {SpringApplication.run(ApplicationStart.class, args); }}
点击run()方法进入SpringApplication类中 , 依次查看调用方法;
public ConfigurableApplicationContext run(String... args) {refreshContext(context);}private void refreshContext(ConfigurableApplicationContext context) {refresh(context);}protected void refresh(ApplicationContext applicationContext) {((AbstractApplicationContext) applicationContext).refresh();} @Overridepublic void refresh() throws BeansException, IllegalStateException {invokeBeanFactoryPostProcessors(beanFactory);} protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());}
到此再点击进入org.springframework.context.support.PostProcessorRegistrationDelegate类中;
【Springboot中@Import的使用原理】public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);} private static void invokeBeanDefinitionRegistryPostProcessors(Collection extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {postProcessor.postProcessBeanDefinitionRegistry(registry); }}
再点击postProcessBeanDefinitionRegistry()方法进入org.springframework.context.annotation.ConfigurationClassPostProcessor类中;
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {processConfigBeanDefinitions(registry);} public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {// Parse each @Configuration class ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);parser.parse(candidates);}
这里再点击parse()方法进入org.springframework.context.annotation.ConfigurationClassParser类当中;
public void parse(Set configCandidates) {processDeferredImportSelectors();}private void processDeferredImportSelectors() {String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);}
稿源:(未知)
【傻大方】网址:http://www.shadafang.com/c/111J304252020.html
标题:Springboot中@Import的使用原理