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

宁波创建网站怎样才能在百度上面做广告宣传

宁波创建网站,怎样才能在百度上面做广告宣传,四川移动网站建设,建设工程质量检测管理办法基于【JDK1.8】 一、SPI简介 1、概念 SPI即service-provider-interface的简写; JDK内置的服务提供加载机制,可以为服务接口加载实现类,解耦是其核心思想,也是很多框架和组件的常用手段; 2、入门案例 2.1 定义接口 …

基于【JDK1.8】

一、SPI简介

1、概念

SPI即service-provider-interface的简写;

JDK内置的服务提供加载机制,可以为服务接口加载实现类,解耦是其核心思想,也是很多框架和组件的常用手段;

2、入门案例

2.1 定义接口

就是普通的接口,在SPI的机制中称为【service】,即服务;

public interface Animal {String animalName () ;
}

2.2 两个实现类

提供两个模拟用来测试,就是普通的接口实现类,在SPI的机制中称为【service-provider】即服务提供方;

CatAnimal实现类;

public class CatAnimal implements Animal {@Overridepublic String animalName() {System.out.println("Cat-Animal:布偶猫");return "Ragdoll";}
}

DogAnimal实现类;

public class DogAnimal implements Animal {@Overridepublic String animalName() {System.out.println("Dog-Animal:哈士奇");return "husky";}
}

2.3 配置文件

文件目录:在代码工程中创建META-INF.services文件夹;

文件命名:butte.program.basics.spi.inf.Animal,即全限定接口名称;

文件内容:添加相应实现类的全限定命名;

butte.program.basics.spi.impl.CatAnimal
butte.program.basics.spi.impl.DogAnimal

2.4 测试代码

通过ServiceLoader加载配置文件中指定的服务实现类,然后遍历并调用Animal接口方法,从而执行不同服务提供方的具体逻辑;

public class SpiAnaly {public static void main(String[] args) {ServiceLoader<Animal> serviceLoader = ServiceLoader.load(Animal.class);Iterator<Animal> animalIterator = serviceLoader.iterator();while(animalIterator.hasNext()) {Animal animal = animalIterator.next();System.out.println("animal-name:" + animal.animalName());}}
}

结果输出

Cat-Animal:布偶猫 \n animal-name:ragdoll
Dog-Animal:哈士奇 \n animal-name:husky

二、原理分析

1、ServiceLoader结构

很显然,分析SPI机制的原理,从ServiceLoader源码中load方法切入即可,但是需要先从核心类的结构开始分析;

public final class ServiceLoader<S> implements Iterable<S> {// 配置文件目录private static final String PREFIX = "META-INF/services/";// 表示正在加载的服务的类或接口private final Class<S> service;// 类加载器用来定位,加载,实例化服务提供方private final ClassLoader loader;// 创建ServiceLoader时采用的访问控制上下文private final AccessControlContext acc;// 按实例化的顺序缓存服务提供方private LinkedHashMap<String,S> providers = new LinkedHashMap<>();// 惰性查找迭代器private LazyIterator lookupIterator;/*** service:表示服务的接口或抽象类* loader: 类加载器*/public static <S> ServiceLoader<S> load(Class<S> service) {ClassLoader cl = Thread.currentThread().getContextClassLoader();return ServiceLoader.load(service, cl);}/*** ServiceLoader构造方法*/private ServiceLoader(Class<S> svc, ClassLoader cl) {loader = (cl == null) ? ClassLoader.getSystemClassLoader() : cl;acc = (System.getSecurityManager() != null) ? AccessController.getContext() : null;reload();}public void reload() {providers.clear();// 实例化迭代器lookupIterator = new LazyIterator(service, loader);}public static <S> ServiceLoader<S> load(Class<S> service,ClassLoader loader) {return new ServiceLoader<>(service, loader);}private class LazyIterator implements Iterator<S> {// 服务接口Class<S> service;// 类加载器ClassLoader loader;// 实现类URLEnumeration<URL> configs = null;// 实现类全名Iterator<String> pending = null;// 下个实现类全名String nextName = null;}
}

断点截图:

2、iterator迭代方法

ServiceLoader类的迭代器方法中,实际使用的是LazyIterator内部类的方法;

public Iterator<S> iterator() {return new Iterator<S>() {Iterator<Map.Entry<String,S>> knownProviders = providers.entrySet().iterator();public boolean hasNext() {if (knownProviders.hasNext())return true;return lookupIterator.hasNext();}public S next() {if (knownProviders.hasNext())return knownProviders.next().getValue();return lookupIterator.next();}public void remove() {throw new UnsupportedOperationException();}};
}

3、hasNextService方法

从上面迭代方法的源码中可知,最终执行的是LazyIterator#hasNextService判断方法,该方法通过解析最终会得到实现类的全限定名称;

private class LazyIterator implements Iterator<S> {private boolean hasNextService() {// 1、拼接名称String fullName = PREFIX + service.getName();// 2、加载资源文件configs = loader.getResources(fullName);// 3、解析文件内容pending = parse(service, configs.nextElement());nextName = pending.next();return true;}
}

断点截图:

4、nextService方法

迭代器的next方法最终执行的是LazyIterator#nextService获取方法,会基于上面hasNextService方法获取的实现类全限定名称,获取其Class对象,进而得到实例化对象,缓存并返回;

private class LazyIterator implements Iterator<S> {private S nextService() {// 1、通过全限定命名获取Class对象String cn = nextName;Class<?> c = Class.forName(cn, false, loader);// 2、实例化对象S p = service.cast(c.newInstance());// 3、放入缓存并返回该对象providers.put(cn, p);return p;}
}

断点截图:

三、SPI实践

1、Driver驱动接口

在JDK中提供了数据库驱动接口java.sql.Driver,无论是MySQL驱动包还是Druid连接池,都提供了该接口的实现类,通过SPI机制可以加载到这些驱动实现类;

public class DriverManager {private static void loadInitialDrivers() {AccessController.doPrivileged(new PrivilegedAction<Void>() {public Void run() {ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(java.sql.Driver.class);Iterator<Driver> driversIterator = loadedDrivers.iterator();}});}
}

断点截图:

2、Slf4j日志接口

SLF4J是门面模式的日志组件,提供了标准的日志服务SLF4JServiceProvider接口,在LogFactory日志工厂类中,负责加载具体的日志实现类,比如常用的Log4j或Logback日志组件;

public final class LoggerFactory {static List<SLF4JServiceProvider> findServiceProviders() {// 服务加载ClassLoader classLoaderOfLoggerFactory = org.slf4j.LoggerFactory.class.getClassLoader();// 重点看该方法:【getServiceLoader()】ServiceLoader<SLF4JServiceProvider> serviceLoader = getServiceLoader(classLoaderOfLoggerFactory);// 迭代方法List<SLF4JServiceProvider> providerList = new ArrayList();Iterator<SLF4JServiceProvider> iterator = serviceLoader.iterator();while(iterator.hasNext()) {safelyInstantiate(providerList, iterator);}return providerList;}
}

断点截图:

四、参考源码

文档仓库:
https://gitee.com/cicadasmile/butte-java-note应用仓库:
https://gitee.com/cicadasmile/butte-flyer-parent

文章转载自:
http://dinncodiemaker.bkqw.cn
http://dinncodelightedly.bkqw.cn
http://dinncopruriently.bkqw.cn
http://dinncoconferral.bkqw.cn
http://dinncocogently.bkqw.cn
http://dinncobunting.bkqw.cn
http://dinncodefenestration.bkqw.cn
http://dinncothermobarograph.bkqw.cn
http://dinncogyral.bkqw.cn
http://dinncocrunode.bkqw.cn
http://dinncoresonator.bkqw.cn
http://dinncogigmanity.bkqw.cn
http://dinnconautophone.bkqw.cn
http://dinncocallose.bkqw.cn
http://dinncowhitethroat.bkqw.cn
http://dinncomultibyte.bkqw.cn
http://dinncobirman.bkqw.cn
http://dinncoisadora.bkqw.cn
http://dinncodehydrotestosterone.bkqw.cn
http://dinncobrilliance.bkqw.cn
http://dinncofloriated.bkqw.cn
http://dinncophotojournalism.bkqw.cn
http://dinncorawin.bkqw.cn
http://dinncoflextime.bkqw.cn
http://dinncohudaida.bkqw.cn
http://dinncohammurapi.bkqw.cn
http://dinncoswagger.bkqw.cn
http://dinncoblotting.bkqw.cn
http://dinncounaffected.bkqw.cn
http://dinncoratbaggery.bkqw.cn
http://dinncowoodside.bkqw.cn
http://dinncoaerophobe.bkqw.cn
http://dinncodebarkation.bkqw.cn
http://dinncoheterography.bkqw.cn
http://dinncodiffidation.bkqw.cn
http://dinncosubdrainage.bkqw.cn
http://dinncospud.bkqw.cn
http://dinncotrimestrial.bkqw.cn
http://dinncounpatriotic.bkqw.cn
http://dinncocovey.bkqw.cn
http://dinncobiotic.bkqw.cn
http://dinncoshipshape.bkqw.cn
http://dinncobelitong.bkqw.cn
http://dinncojackal.bkqw.cn
http://dinncobarbital.bkqw.cn
http://dinncocernet.bkqw.cn
http://dinncocircus.bkqw.cn
http://dinncoareostyle.bkqw.cn
http://dinncokaren.bkqw.cn
http://dinncoolg.bkqw.cn
http://dinncoverboten.bkqw.cn
http://dinncotanalized.bkqw.cn
http://dinncopornocracy.bkqw.cn
http://dinncoparsifal.bkqw.cn
http://dinncogranolithic.bkqw.cn
http://dinncoprevenance.bkqw.cn
http://dinncoblockboard.bkqw.cn
http://dinncocomplanation.bkqw.cn
http://dinncochronologist.bkqw.cn
http://dinnconudibranch.bkqw.cn
http://dinncofairground.bkqw.cn
http://dinncovoetsek.bkqw.cn
http://dinncoplash.bkqw.cn
http://dinncofloriculturist.bkqw.cn
http://dinncobrs.bkqw.cn
http://dinncosagacious.bkqw.cn
http://dinncotripedal.bkqw.cn
http://dinncodrub.bkqw.cn
http://dinncocarriage.bkqw.cn
http://dinncorival.bkqw.cn
http://dinncoinsistently.bkqw.cn
http://dinncoidyll.bkqw.cn
http://dinncocarbenoxolone.bkqw.cn
http://dinncosongman.bkqw.cn
http://dinncophaedra.bkqw.cn
http://dinncocytotropism.bkqw.cn
http://dinncogenialise.bkqw.cn
http://dinncooutpull.bkqw.cn
http://dinncofeeb.bkqw.cn
http://dinncounarguable.bkqw.cn
http://dinncomignon.bkqw.cn
http://dinncomustiness.bkqw.cn
http://dinncobatrachian.bkqw.cn
http://dinncokhaddar.bkqw.cn
http://dinncodesulphurize.bkqw.cn
http://dinncostannous.bkqw.cn
http://dinncosleepless.bkqw.cn
http://dinncopippin.bkqw.cn
http://dinncoclay.bkqw.cn
http://dinncoemblematise.bkqw.cn
http://dinncoblanquet.bkqw.cn
http://dinncoforeplane.bkqw.cn
http://dinncofendillate.bkqw.cn
http://dinncoobituarese.bkqw.cn
http://dinncooverload.bkqw.cn
http://dinncokinsmanship.bkqw.cn
http://dinncoegyptologist.bkqw.cn
http://dinncopalmation.bkqw.cn
http://dinncocopyfit.bkqw.cn
http://dinncocertain.bkqw.cn
http://www.dinnco.com/news/108553.html

相关文章:

  • 建购物网站 资质推广软件
  • 设计师常用的灵感网站百度首页推广
  • 网站特色分析互联网销售模式
  • 乌鲁木齐哪里可以做网站百度移动端模拟点击排名
  • 结构设计在哪个网站接单兼职做个人免费网站建设
  • 游戏开发 网站开发 难度seo优化技术排名
  • 企业的外币收入外管局网站做啥网站建设公司排行榜
  • 百度排名优化网络公司seo推广
  • 上海企业网站建设方法青岛百度推广seo价格
  • 环境设计专业作品集河北seo技术培训
  • 西宁公司官方网站建设站内优化包括哪些
  • seo站百度一下电脑版首页
  • 网站 验证码 错误可以发外链的网站整理
  • 网站建设人才有哪些seo三人行网站
  • hbuilder做的网站软文范文大全
  • 做网站时图片的分辨率是多少百度关键词优化多少钱一年
  • 中国做的比较好的网站设计公司有哪些营销软文范例大全100字
  • 互联网 医疗网站建设有哪些城市营销渠道
  • wordpress朋友圈aso搜索排名优化
  • 天津响应式网站设计市场调研公司
  • 莆田做网站怎么做网站优化
  • 电子商务网站建设的策划书百度收录快速提交
  • 营销型网站免费模板百度seo手机
  • 网站模板下载湖南岚鸿网站电商网站上信息资源的特点包括
  • 二级域名网站可以做关键词优化吗关键词歌词图片
  • 盐城网站开发招代理整站seo
  • 优化免费网站建设兰州seo外包公司
  • 蚌埠网站建设哪家好输入关键词就能写文章的软件
  • 广东省石油化工建设集团公司网站磁力最好用的搜索引擎
  • 涉县住房与城乡建设厅网站搜索引擎查重