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

北京网站建设的服务商盐城营销网站建设

北京网站建设的服务商,盐城营销网站建设,请说明网站建设的一般过程包括哪些,金马国旅网站建设文章目录 一、初步认识1、概念2、工作原理3、作用场景 二、源码分析1、ServiceLoader结构2、相关字段3、核心方法 三、案例connector连接器小案例1、新建SPI项目2、创建扩展实现项目1-MongoDB3、创建扩展实现项目2-Oracle4、测试 Spring应用1、创建study工程2、创建forlan-test… 文章目录 一、初步认识1、概念2、工作原理3、作用场景 二、源码分析1、ServiceLoader结构2、相关字段3、核心方法 三、案例connector连接器小案例1、新建SPI项目2、创建扩展实现项目1-MongoDB3、创建扩展实现项目2-Oracle4、测试 Spring应用1、创建study工程2、创建forlan-test工程3、进阶使用 一、初步认识 1、概念 SPI全称为 Service Provider Interface是Java提供的一种服务发现机制用于实现组件之间的解耦和扩展。 它允许开发人员定义一组接口Service Interface并允许其他开发人员通过实现这些接口来提供具体的服务实现Service Provider而无需修改Java平台的源代码。 2、工作原理 定义接口开发人员首先定义一个接口该接口定义了一组操作或功能。提供实现其他开发人员可以通过实现该接口来提供具体的服务实现。这些实现通常以独立的模块或库的形式提供。配置文件在Java的SPI机制中开发人员需要在META-INF/services目录下创建一个以接口全限定名命名的文件文件内容为提供该接口实现的类的全限定名列表。加载服务Java的SPI机制会在运行时自动加载并实例化这些服务提供者的实现类使得开发人员可以通过接口来访问具体的服务实现。 3、作用场景 它提供了一种松耦合的方式可插拔的设计来扩展应用程序的功能。通过SPI开发人员可以在不修改核心代码的情况下通过添加新的实现来增加应用程序的功能像很多框架都使用到了比如Dubbo、JDBC。 通过服务方指定好接口具体由第三方去实现就像JDBC中定义好了一套规范MySQL、Oracle、MongoDB按照这套规范具体去实现通过在ClassPath路径下的META-INF/services文件夹中查找文件自动加载文件里所定义的类。 二、源码分析 核心类ServiceLoader核心方法load。 ServiceLoader是加载SPI服务的入口通过调用ServiceLoader.load()方法可以加载指定的Service会根据配置文件中指定的包名和类名动态地加载符合条件的所有实现类并创建一个Service Provider的集合通过遍历这个集合可以获取具体的实现类对象。 1、ServiceLoader结构 2、相关字段 // 配置文件的路径 private static final String PREFIX META-INF/services/;// 正在加载的服务类或者接口 private final ClassS service;// 类加载器 private final ClassLoader loader;// 访问控制上下文对象 private final AccessControlContext acc;// 缓存已经加载的服务类按照顺序实例化 private LinkedHashMapString,S providers new LinkedHashMap();// 内部类真正加载服务类 private LazyIterator lookupIterator;3、核心方法 创建了一些属性service和loader等最重要的是实例化了内部类LazyIterator public final class ServiceLoaderS implements IterableS {/*** Creates a new service loader for the given service type, using the* current threads {linkplain java.lang.Thread#getContextClassLoader* context class loader}.*/public static S ServiceLoaderS load(ClassS service) {// 获取当前线程的上下文类加载器ClassLoader cl Thread.currentThread().getContextClassLoader();// 通过请求的Class和ClassLoader创建ServiceLoaderreturn ServiceLoader.load(service, cl);}private ServiceLoader(ClassS svc, ClassLoader cl) {// 加载的接口不能为空service Objects.requireNonNull(svc, Service interface cannot be null);// 类加载器loader (cl null) ? ClassLoader.getSystemClassLoader() : cl;// 访问权限的上下文对象acc (System.getSecurityManager() ! null) ? AccessController.getContext() : null;reload();}/*** Clear this loaders provider cache so that all providers will be* reloaded.*/public void reload() {// 清空已经加载的服务类providers.clear();// 实例化内部类迭代器LazyIterator lookupIterator new LazyIterator(service, loader);} }LazyIterator很重要查找实现类和创建实现类的过程都在它里面完成。 private class LazyIterator implements IteratorS{ClassS service;ClassLoader loader;EnumerationURL configs null;IteratorString pending null;String nextName null; private LazyIterator(ClassS service, ClassLoader loader) {this.service service;this.loader loader;}private boolean hasNextService() {省略详细代码...}private S nextService() {省略详细代码...} }当我们调用iterator.hasNext实际上调用的是LazyIterator的hasNextService方法判断是否还有下一个服务提供者 private boolean hasNextService() {if (nextName ! null) {return true;}if (configs null) {try {// private static final String PREFIX META-INF/services/;// META-INF/services/ 该对象表示的类或接口的全限定类名类路径接口名String fullName PREFIX service.getName();// 将文件路径转成URL对象if (loader null)configs ClassLoader.getSystemResources(fullName);elseconfigs loader.getResources(fullName);} catch (IOException x) {fail(service, Error locating configuration files, x);}}while ((pending null) || !pending.hasNext()) {// EnumerationURL configs是否包含更多元素if (!configs.hasMoreElements()) {return false;}// 解析URL文件对象读取内容pending parse(service, configs.nextElement());}// 拿到下一个实现类的类名nextName pending.next();return true; } private S nextService() {当我们调用iterator.next方法的时候实际上调用的是LazyIterator的nextService方法获取下一个服务提供者它通过反射的方式创建实现类的实例并返回 private S nextService() {if (!hasNextService())throw new NoSuchElementException();String cn nextName;nextName null;Class? c null;try {// 创建类的Class对象c Class.forName(cn, false, loader);} catch (ClassNotFoundException x) {fail(service,Provider cn not found);}if (!service.isAssignableFrom(c)) {fail(service,Provider cn not a subtype);}try {// 通过newInstance实例化S p service.cast(c.newInstance());// 放入providers缓存providers.put(cn, p);return p;} catch (Throwable x) {fail(service,Provider cn could not be instantiated,x);}throw new Error(); // This cannot happen }三、案例 connector连接器小案例 1、新建SPI项目 导入依赖到pom.xml artifactIdjava-spi-connector/artifactId写1个简单接口 public interface IBaseInfo {public void url(); }2、创建扩展实现项目1-MongoDB 导入依赖到pom.xml artifactIdmongodb-connector/artifactIddependenciesdependencygroupIdcn.forlan/groupIdartifactIdjava-spi-connector/artifactIdversion1.0-SNAPSHOT/version/dependency /dependencies写1个简单实现类重新url方法打印mongoDB:url public class MongoDBBaseInfo implements IBaseInfo{Overridepublic void url() {System.out.println(mongoDB:url);} }在resources目录下创建 META-INF/services目录创建一个文件命名为接口的类路径接口名必须内容为实现类路径类名 3、创建扩展实现项目2-Oracle 导入依赖到pom.xml artifactIdoracle-connector/artifactIddependenciesdependencygroupIdcn.forlan/groupIdartifactIdjava-spi-connector/artifactIdversion1.0-SNAPSHOT/version/dependency /dependencies写1个简单实现类重新url方法打印oracle:url public class OracleBaseInfo implements IBaseInfo{Overridepublic void url() {System.out.println(oracle:url);} }在resources目录下创建 META-INF/services目录创建一个文件命名为接口的类路径接口名必须内容为实现类路径类名 4、测试 测试方法 ServiceLoaderIBaseInfo serviceLoader ServiceLoader.load(IBaseInfo.class); IteratorIBaseInfo iterator serviceLoader.iterator(); while (iterator.hasNext()){IBaseInfo next iterator.next();next.url(); }它会根据你导入不同的依赖出现不同的效果 导入MongoDB 导入Oracle Spring应用 我们要说的应用就是SpringFactoriesLoader工具类类似Java中的SPI机制只不过它更优不会一次性加载所有类可以根据key进行加载 作用从classpath/META-INF/spring.factories文件中根据key去加载对应的类到spring IoC容器中 1、创建study工程 创建ForlanCore类 package cn.forlan.spring;public class ForlanCore {public void code() {System.out.println(Forlan疯狂敲代码);} }创建ForlanConfig配置类 package cn.forlan.spring;import org.springframework.beans.factory.annotation.Configurable; import org.springframework.context.annotation.Bean;Configurable public class ForlanConfig {Beanpublic ForlanCore forlanCore() {return new ForlanCore();} }2、创建forlan-test工程 打包study为jar引入依赖 dependencygroupIdcn.forlan/groupIdartifactIdstudy1/artifactIdversion1.0-SNAPSHOT/version /dependency测试获取属性 SpringBootApplication public class ForlanTestApplication {public static void main(String[] args) {ApplicationContext applicationContext SpringApplication.run(ForlanTestApplication.class, args);ForlanCore fcapplicationContext.getBean(ForlanCore.class);fc.code();} }运行报错原因很简单ForlanCore在spring容器中找不到没有注入 Exception in thread main org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type cn.forlan.spring.ForlanCore availableat org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:352)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:343)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1127)at cn.forlan.ForlanTestApplication.main(ForlanTestApplication.java:12)解决方法 在study工程的resources下新建文件夹META-INF在文件夹下面新建spring.factories文件配置key和value然后重新打包即可 org.springframework.boot.autoconfigure.EnableAutoConfigurationcn.forlan.spring.ForlanConfig注keyEnableAutoConfiguration的全路径,value配置类的全路径 3、进阶使用 指定配置文件生效条件 在META-INF/增加配置文件spring-autoconfigure-metadata.properties cn.forlan.spring.ForlanConfig.ConditionalOnClasscn.forlan.spring.Study格式自动配置的类全名.条件值 该配置的意思是项目中com.forlan.spring包下存在Study才会加载ForlanConfig 执行之前的测试用例运行报错 解决在当前工程指定包下创建一个Study即可
http://www.zqtcl.cn/news/997804/

相关文章:

  • 青海做网站哪家好旅游网站的功能及建设
  • 百度网站优化工具汉川网页设计
  • 网站标签优化怎么做可以看图片的地图什么软件
  • 品牌网站建设9小蝌蚪9wordpress会务网站模版
  • 免费推广网站入口202网页与网站建设
  • 武夷山市网站建设网站标签制作
  • 广州网站定制开发方案河南省新闻发布会直播
  • 普陀网站建设哪家便宜网站建设辶金手指排名十五
  • 网站怎么做百度百科租房网站开发视频教程
  • 动态做网站做自己的网站不是免费的
  • 小学校园门户网站建设方案宁波seo软件
  • 想自己做网站做推广从哪些方面进行网站建设
  • 北京南站在哪个区哪个街道html表白简单代码
  • 海口网站建设流程郑州三牛网站建设
  • 谁有国外hs网站沈阳关键字优化公司
  • wordpress双站企业品牌类网站
  • 网站架构软件做淘客app要网站吗
  • 云南云桥建设股份有限公司官方网站汽车seo是什么意思
  • 陕西省建设厅执业资格注册中心网站报名系统外贸网站 字体
  • 个人html网站百度一下生活更好
  • 做网站公司徐汇服务器 网站 搬家
  • 河北省和城乡建设厅网站首页单页设计图片
  • 海东地网站建设南京市建设局网站栖霞
  • 1g做网站空间a3网站建设
  • 海络网站室内设计工作前景
  • 柳州旅游网站建设橱柜设计师培训
  • 做网站属于什么专业个人是否可以申请网址
  • 品牌网站建是啥网站点击率怎么建
  • 上海市质量工程建设管理协会网站网站开发制作公司排行
  • 网站空间租用多少钱怎么在外贸公司拿订单