当前位置: 首页 > news >正文

做进化树的网站电工应用技术网站资源建设

做进化树的网站,电工应用技术网站资源建设,东莞市永铭装饰有限公司,打游戏一天赚200元SpringBoot启动流程分析之创建SpringApplication对象(一) 目录#xff1a; 文章目录 SpringBoot启动流程分析之创建SpringApplication对象(一)1、SpringApplication的构造方法1.1、推断应用程序类型1.2、设置Initializers1.3、设置Listener1.4、推断main方法所在类 流程分析…SpringBoot启动流程分析之创建SpringApplication对象(一) 目录 文章目录 SpringBoot启动流程分析之创建SpringApplication对象(一)1、SpringApplication的构造方法1.1、推断应用程序类型1.2、设置Initializers1.3、设置Listener1.4、推断main方法所在类 流程分析 1、SpringApplication的构造方法 来看一下在SpringApplication对象的构造方法中都做了哪些事。 public SpringApplication(Class?... primarySources) {this(null, primarySources); }SuppressWarnings({ unchecked, rawtypes }) public SpringApplication(ResourceLoader resourceLoader, Class?... primarySources) {this.resourceLoader resourceLoader;//判断primarySources不能为空Assert.notNull(primarySources, PrimarySources must not be null);//将primarySources放入SpringApplication的全局变量primarySourcesSet集合中this.primarySources new LinkedHashSet(Arrays.asList(primarySources));//从类路径中推断应用程序类型放到SpringApplication的全局变量webApplicationType this.webApplicationType WebApplicationType.deduceFromClasspath();//从META-INF/spring.factories文件中获取ApplicationContextInitializer接口的实现类并利用反射创建对象返回放入SpringApplication的全局变量initializersList集合中setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));//同上也是从META-INF/spring.factories文件中获取ApplicationListener接口的实现类并利用反射创建对象返回放入SpringApplication的全局变量listenersList集合中setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));//通过获取当前调用栈找到入口方法main所在的类放入SpringApplication的全局变量mainApplicationClass this.mainApplicationClass deduceMainApplicationClass(); }1.1、推断应用程序类型 private static final String[] SERVLET_INDICATOR_CLASSES { javax.servlet.Servlet,org.springframework.web.context.ConfigurableWebApplicationContext };private static final String WEBFLUX_INDICATOR_CLASS org. springframework.web.reactive.DispatcherHandler;private static final String WEBMVC_INDICATOR_CLASS org.springframework. web.servlet.DispatcherServlet;private static final String JERSEY_INDICATOR_CLASS org.glassfish.jersey.servlet.ServletContainer;static WebApplicationType deduceFromClasspath() {//ClassUtils.isPresent()从默认classloader中判断是否存在对应的类型if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null) !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {return WebApplicationType.REACTIVE;}for (String className : SERVLET_INDICATOR_CLASSES) {if (!ClassUtils.isPresent(className, null)) {return WebApplicationType.NONE;}}return WebApplicationType.SERVLET; }推断逻辑是 先是判断默认的classloader中是否存在org.springframework.web.reactive.DispatcherHandler、且不存在org.springframework.web.servlet.DispatcherServlet、org.glassfish.jersey.servlet.ServletContainer如果为true返回WebApplicationType.REACTIVE 然后循环String数组判断如果默认的classloader中是否不存在javax.servlet.Servlet和org.springframework.web.context.ConfigurableWebApplicationContext如果不存在则认为不是web应用程序返回WebApplicationType.NONE 最后是返回WebApplicationType.SERVLET。 三种返回类型的解释如下 1、WebApplicationType.NONE:不是web应用程序2、WebApplicationType.SERVLET:基于servlet的Web应用程序运行3、WebApplicationType.REACTIVE响应式的web应用程序1.2、设置Initializers 传入参数是class类型即ApplicationContextInitializer.class最终调用方法是getSpringFactoriesInstances注意第二个参数传的是一个空的Class数组则加载所有的配置的类方便后续给定限定类型的时候无需再次加载直接从cache中读取。 SpringFactoriesLoader.loadFactoryNames(Class? factoryClass, Nullable ClassLoader classLoader)这个方法其作用是使用给定的类加载器从“META-INF/spring.factories”加载给定类型的工厂实现的完全限定类名即得到所有ApplicationContextInitializer接口实现类的完全限定类名去重。 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));private T CollectionT getSpringFactoriesInstances(ClassT type) {return getSpringFactoriesInstances(type, new Class?[] {});}private T CollectionT getSpringFactoriesInstances(ClassT type,Class?[] parameterTypes, Object... args) {ClassLoader classLoader getClassLoader();// Use names and ensure unique to protect against duplicates//得到所有ApplicationContextInitializer接口的实现类SetString names new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));//创建所有ApplicationContextInitializer接口实现类的实例ListT instances createSpringFactoriesInstances(type, parameterTypes,classLoader, args, names);//根据order排序AnnotationAwareOrderComparator.sort(instances);return instances; }随后当做参数传递到createSpringFactoriesInstances方法中这个方法主要作用就是根据传入的type类型parameterTypes参数类型空Class数组以及得到的完全限定类名集合创建对象实例其中getDeclaredConstructor方法作用是得到指定参数类型的构造方法parameterTypes为空数组即的得到的就是默认构造方法。构造方法基本都是空的所以无需关心创建Initializers实例的时候在构造方法中执行了什么操作。这些对象的initialize方法会在后面的run方法中被调用。 SuppressWarnings(unchecked) private T ListT createSpringFactoriesInstances(ClassT type,Class?[] parameterTypes, ClassLoader classLoader, Object[] args,SetString names) {//new 一个跟检索出来的接口实现类相同size的ListListT instances new ArrayList(names.size());for (String name : names) {try {//通过类加载器加载类Class? instanceClass ClassUtils.forName(name, classLoader);//判断是否为ApplicationContextInitializer接口的实现类Assert.isAssignable(type, instanceClass);//得到指定参数类型的构造方法Constructor? constructor instanceClass.getDeclaredConstructor(parameterTypes);//创建对象T instance (T) BeanUtils.instantiateClass(constructor, args);//放到List中返回instances.add(instance);}catch (Throwable ex) {throw new IllegalArgumentException(Cannot instantiate type : name, ex);}}return instances; }spring.factories文件内容中Initializers如下。 1.3、设置Listener 这一步跟上面设置Initializers执行的操作是一样的。spring.factories文件内容中Listener如下。 整理一下Listener对应的Event 监听器事件类型BackgroundPreinitializerApplicationStartingEvent、ApplicationEnvironmentPreparedEvent、ApplicationPreparedEvent、ApplicationStartedEvent、ApplicationReadyEvent、ApplicationFailedEvent、ApplicationContextInitializedEventClearCachesApplicationListenerContextRefreshedEventParentContextCloserApplicationListenerParentContextAvailableEventFileEncodingApplicationListenerApplicationEnvironmentPreparedEventAnsiOutputApplicationListenerApplicationEnvironmentPreparedEventConfigFileApplicationListenerApplicationEnvironmentPreparedEvent、ApplicationPreparedEventDelegatingApplicationListenerApplicationEnvironmentPreparedEventClasspathLoggingApplicationListenerApplicationEnvironmentPreparedEvent、ApplicationFailedEventLoggingApplicationListenerApplicationStartingEvent、ApplicationEnvironmentPreparedEvent、ApplicationPreparedEvent、ContextClosedEvent、ApplicationFailedEventLiquibaseServiceLocatorApplicationListenerApplicationStartingEvent 1.4、推断main方法所在类 StackTraceElement数组包含了StackTrace(堆栈轨迹)的内容通过遍历它可以得到当前方法以及其定义类、调用行数等信息。 private Class? deduceMainApplicationClass() {try {//获取StackTraceElement数组也就是这个栈的信息。StackTraceElement[] stackTrace new RuntimeException().getStackTrace();for (StackTraceElement stackTraceElement : stackTrace) {if (main.equals(stackTraceElement.getMethodName())) {//stackTraceElement.getClassName(),得到定义类即main方法所在类return Class.forName(stackTraceElement.getClassName());}}}catch (ClassNotFoundException ex) {// Swallow and continue}return null; }SpringApplication对象的创建过程就完成了。 Springboot 启动还可以使用流式API SpringApplicationBuilder的方式启动 SpringBootApplication public class RegisterApplication {public static void main(String[] args) {new SpringApplicationBuilder(RegisterApplication.class)// 设置当前应用类型.web(WebApplicationType.SERVLET)// 设置 banner 横幅打印方式、有关闭、日志、控制台.bannerMode(Banner.Mode.OFF)// 设置自定义的 banner.banner()// 追加自定义的 initializer 到集合中 .initializers()// 追加自定义的 listeners 到集合中.listeners().run(args);} }
http://www.hkea.cn/news/14303861/

相关文章:

  • 增长超人做网站多少钱网站如何做微信支付宝支付宝
  • 很长的网站域名怎么做短给素材网站做签约设计不想做了
  • 口碑好的做网站网站建设服务8
  • 关于做书的网站二手交易网站设计怎么做
  • 网站构建工具怎么做网站演示
  • python做网站稳定吗深圳 网站设计公司排名
  • 北京网站搭建多少钱权威发布是什么意思
  • 采集网站如何收录新手网站建设教程
  • 网站小程序开发公司北京建设网网站
  • 七米网站开发移动端网站建站视频
  • 教育网站开发用例图seo这个行业怎么样
  • 服饰网站建设模板企业建设网站怎么做账
  • 镇江网站建设平台网站logo怎么做动态图
  • 做期权注册网站做网站的软件工程师
  • 网站模板打包下载wordpress页面如何显示分类目录
  • 中国十大网站建设公司郑州高端网站
  • wordpress安装插件导致网站前端h5是什么意思
  • 制作网站图文教程网站互点都是怎么做的
  • 免费背景图片素材网站不用cms怎么做网站
  • 渭南华阴建设银行的网站是多少做爰视频免费观看网站
  • 网费一年多少钱做模板网站乐云seo效果好
  • 建设网站都要学些什么手续网站开发名片
  • 美团网站除佣金表格怎么做网站建设的费用是不是含税的
  • 如何查外贸网站外链自建营销型网站模板
  • 郯城地建设局网站搜索引擎优化要考虑哪些方面
  • 江苏盐城有做淘宝网站的吗开发公司五一节前安全生产工作部署会
  • 厦门网站制作推广网站设计方案书
  • 厦门建设工程招标中心的网站有域名有服务器如何做网站
  • 商业网站如何备案公司网页设计
  • 专业的金融行业网站开发天猫商城支付方式