做外贸的网站如何选择服务器家具设计师要学哪些软件
2026/2/21 4:48:29 网站建设 项目流程
做外贸的网站如何选择服务器,家具设计师要学哪些软件,博客网站推广,做百度企业网站有什么好处问题引入 SpringBoot最核心的一个东西就是自动配置#xff0c;自动配置的原理是什么#xff1f; 我们知道Spring最开始是通过xml文件配置#xff0c;来告诉Spring要创建哪些类、哪些Bean。 后来进化为可以通过注解来配置#xff0c;这样就不用去写xml文件了#xff0c;…问题引入SpringBoot最核心的一个东西就是自动配置自动配置的原理是什么我们知道Spring最开始是通过xml文件配置来告诉Spring要创建哪些类、哪些Bean。后来进化为可以通过注解来配置这样就不用去写xml文件了只需要告诉Spring去扫描哪些包就可以了。那么问题来了如果是一个三方服务框架包我怎么知道要去扫描哪些包呢很多时候我们还是只能通过Bean的方式去创建一些复杂的服务可能需要创建很多Bean我们怎么知道要创建哪些Bean呢这些Bean的关联关系又是怎样的呢用起来太麻烦了很多时候我们并不想知道实现的具体细节我们只希望拿来就能用怎么办呢于是SpringBoot来了它可以自动完成配置创建并注入需要的Bean不需要我们自己去创建了若有的创建Bean的工作都由提供服务的服务者去创建他们自己实现的当然更清楚怎么用怎么创建系列Bean。那么问题又来了SpringBoot是怎么做到自动配置的呢答案是类Java SPI机制。Java SPI机制一个好的语言、框架设计时候一定要考虑好扩展做好抽象层。例如Java的数据库驱动就是一个好的例子我们使用的都是java.sql包下的抽象层接口根本不用关心是哪种数据库实现细节是什么。一个不好的例子就是Java的日志功能所以抽象做得更好的slf4j-api基本就成了共用接口标准。当然技术在不断发展很多时候我们再设计的时候并不能考虑到那么多例如响应式编程那也是发展了很多年才有projectreactorJava的数据库驱动为什么能让我们不用关心具体实现呢答案就是:SPI(Service Provider Interface)。Java SPI核心类是java.util.ServiceLoader它会去扫描classpath下的META-INF/services目录下的文件文件名是抽象层的全限定名例如java.sql.Driver文件内容是服务提供的具体实现类。如com.mysql.cj.jdbc.DriverJava SPI Druid DriverEnableAutoConfigurationJava SPI的核心类是ServiceLoaderSpringBoot自动配置的核心类是EnableAutoConfiguration。Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Documented Inherited AutoConfigurationPackage Import(AutoConfigurationImportSelector.class) public interface EnableAutoConfiguration { }EnableAutoConfiguration它通过Import(AutoConfigurationImportSelector.class)自动装配了AutoConfigurationImportSelector类。public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered { }AutoConfigurationImportSelector实现了DeferredImportSelector接口DeferredImportSelector又实现了ImportSelector。ImportSelector#selectImports就可以告诉Spring这些类需要被导入。那AutoConfigurationImportSelector会去哪里找需要自动装配的类呢顺着接口selectImports找呗有兴趣可以自己去跟源码这里简单总结一下ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader())找的是AutoConfiguration类META-INF/spring/要找的类的全限定名称.imports文件所以META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports上面的文件配置的类每行一个全部导入还有一个ImportAutoConfigurationImportSelector是处理ImportAutoConfiguration。org.springframework.boot.autoconfigure.AutoConfiguration.imports除了直接导入的还有通过org.springframework.core.io.support.SpringFactoriesLoader#loadFactoryNames导入找的是META-INF/spring.factories文件。spring.factories这个文件中的内容类似properties是key-value形式key是接口全限定名value是具体实现类全限定名多个逗号分隔。spring.factories对于自动导入来说具体的接口是org.springframework.boot.autoconfigure.EnableAutoConfiguration。例如Import({DruidSpringAopConfiguration.class, DruidStatViewServletConfiguration.class, DruidWebStatFilterConfiguration.class, DruidFilterConfiguration.class}) public class DruidDataSourceAutoConfigure {}对过对于EnableAutoConfiguration还是推荐使用新的规范仍在META-INF\spring\org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中这样不用配置key也不用考虑多行的问题直接每行一个就行。实现自己的EnableMyAutoConfiguration知道了原理我们可以动手实现一个我们自己的EnableMyAutoConfiguration。首先是Enable注解import org.springframework.context.annotation.Import; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Import(MyAutoConfigurationImportSelector.class) public interface EnableMyAutoConfiguration { }然后是我们需要处理什么注解呢我们自定义的MyAutoConfigurationimport java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) public interface MyAutoConfiguration { }接下来我们需要一个DeferredImportSelector来加载配置的MyAutoConfiguration类。import org.springframework.boot.context.annotation.ImportCandidates; import org.springframework.context.annotation.DeferredImportSelector; import org.springframework.core.type.AnnotationMetadata; import java.util.List; public class MyAutoConfigurationImportSelector implements DeferredImportSelector { Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { ListString configurations ImportCandidates.load(MyAutoConfiguration.class, this.getClass().getClassLoader()) .getCandidates(); return configurations.toArray(new String[0]); } }使用了MyAutoConfiguration的配置类import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Import; MyAutoConfiguration Import(BzClass.class) public class ConfigurationA { Bean public String name(){ return ConfigurationA; } }配置类中导入了具体的业务类public class BzClass { }然后我们把配置类vip.oschool.custom.ConfigurationA配置到META-INF\spring\vip.oschool.custom.MyAutoConfiguration.imports文件中。然后来一个启动类import org.springframework.context.annotation.ConfigurationClassPostProcessor; import org.springframework.context.support.GenericApplicationContext; EnableMyAutoConfiguration public class Main { public static void main(String[] args) { GenericApplicationContext context new GenericApplicationContext(); context.registerBean(main, Main.class); // ConfigurationClassPostProcessor处理DeferredImportSelector context.registerBean(ConfigurationClassPostProcessor.class); context.refresh(); for (String beanName : context.getBeanDefinitionNames()) { System.out.println(beanName); } } }手动实现自动加载结果我们可以看到所有的配置类都被加载了。starter知道了自动配置原理再来看starter就想吃饭喝水一样简单了。通常我们自己的state人的artifactId是xxxx-spring-boot-starterspring自己的stater是spring-boot-starter-xxxxdruid-spring-boot-starter就是把配置类添加到了spring.factoriesdruid自动配置实现DruidDataSourceAutoConfigure创建了DruidDataSourceWrapper又通过Import导入DruidSpringAopConfiguration等实际业务类。所以我们什么都不用管只需要把druid-spring-boot-starter添加入依赖就可以用了因为DruidSpringAopConfiguration都帮我们创建好了。当然关联的依赖也在druid-spring-boot-starter的pom.xml中导入了。还有一些更符合Spring模式的例如会单独有一个autoconfigure项目来管理自动配置。自动配置的类配置在META-INF\spring\org.springframework.boot.autoconfigure.AutoConfiguration.imports文件。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询