effective java笔记之java服务提供者框架
博主是一名苦逼的大四实习生,现在java从业人员越来越多,面对的竞争越来越大,还没走出校园,就TM可能面临失业,而且对那些增删改查的业务毫无兴趣,于是决定提升自己,在实习期间的时间还是很充裕的,期间自学了很多流行的技术(我差点信了),也重拾了之前忽略的数据结构和算法(虽然还是半吊子,总比一点不会好,哈哈),欢迎大家和我交流,特别是想提升自身技能的小伙伴,我的QQ是673793576,下面开始进入正题~~
以前我看书的时候都是走马观花的看,看完以为都懂了,其实毛都不会,纯属浪费时间,最近在看2本书,effective java 和 java 并发编程实战,两本书绝对是难得的好书,强烈推荐大家去仔细精读,前提是有java基础,不放过书中提到的每一个知识点,不好意思,又写了一段与正题无关的内容,哈哈。。。。
服务提供者框架其实我们并不陌生,从最开始的jdbc编程中,我们就已经遇见了它,常用的数据库有MySQL数据库,Oracle数据库等,这些数据库由于是不同的数据库提供方提供,导致在java连接数据库的连接方式也不一样,这里我们可以把这个连接看成一个服务,作为开发人员,我们只管去调用这个服务,而不需要管这个服务是怎么产生的,服务的生成由这些服务提供者去产生,我们要做的就是指定一个服务提供者的名字,然后就可以得到服务,而无需关注具体实现细节,那么问题来了,我们要获取服务,从哪里获取,直接向服务提供者索要吗?通常的做法是,用一个类似管家的东西来集中管理这些服务的提供者,作为服务消费方,我们直接去找这个管家索要服务
服务提供者框架的几个概念:服务接口以及具体的服务实现类,服务提供者接口(可选)以及具体的实现类,服务提供者的注册类(也就是上文所说的管家)
服务是一个很抽象的概念,既然是服务,它肯定有个作用啊,对应到java中,它应该具有方法,事实上,服务的种类有很多,学过java的都知道,我们可以用一个接口来定义一个服务,然后让不同的实现类去实现这个接口从而实现具体的服务内容。
服务接口:定义了抽象的服务,以及一个或多个方法
服务实现类:实现服务接口,实现具体的方法
服务提供者接口:定义了抽象的服务提供者,提供一个获取服务的方法
服务提供者实现类:实现服务提供者接口,实现具体的方法
服务提供者注册类:提供一个注册服务与调用服务的方法,它是面向服务消费者的
废话不说直接上图

接着上代码
package serviceprovider;
public interface Service {
void print();
}
package serviceprovider;
public class FirstService implements Service {
@Override
public void print() {
System.out.println("第一个服务");
}
}
package serviceprovider;
public class SecondService implements Service {
@Override
public void print() {
System.out.println("第二个服务");
}
}
package serviceprovider;
public interface ServiceProvider {
Service getService();
}
package serviceprovider;
public class FirstServiceProvider implements ServiceProvider {
static{
ServiceManager.registerProvider("firstServiceProvider", new FirstServiceProvider());
}
@Override
public Service getService() {
return new FirstService();
}
}
package serviceprovider;
public class SecondServiceProvider implements ServiceProvider {
static{
ServiceManager.registerProvider("secondServiceProvider", new SecondServiceProvider());
}
@Override
public Service getService() {
return new SecondService();
}
}
package serviceprovider; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; public class ServiceManager { private static final Map<String, ServiceProvider> providers = new ConcurrentHashMap<String, ServiceProvider>(); public static void registerProvider(String name, ServiceProvider p) {
providers.put(name, p);
} public static Service getService(String name) {
ServiceProvider p = providers.get(name);
if (p == null) {
throw new IllegalArgumentException(
"No ServiceProvider registered with name:" + name);
}
return p.getService();
}
}
package serviceprovider;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("serviceprovider.FirstServiceProvider");
Service service = ServiceManager.getService("firstServiceProvider");
service.print();
}
}
执行结果:第二个服务
代码分析:首先定义一个名叫Service的服务,这里只提供一个print()方法,它有两个具体的实现类,第一个实现类的print方法打印出“第一个服务”内容,第二个同理,现在有了服务,还缺服务的提供者,也就是这些服务由谁来提供,同理定义一个提供者接口,既然是服务提供者,总得存在服务吧,没有服务尼玛还提供毛线啊,所以要持有一个取得服务的方法,这里用到了一个静态代码块,是为了提供者在类在初始化时向管理类注册自己,意思就是,管家(提供者管理类),我是XX,我提供XX服务,给我登记一下我的信息。第二个同理。然后来一个测试类,这里看到Class.forName是不是很熟悉,Class.forName("xxx"),会加载这个类的信息,并初始化静态代码块,因为静态对象属于类嘛,但是不会实例化这个对象,除非加上.newInstance()方法,即Class.forName("xxx").newInstance();这里用的是反射,就不细说了。所以在提供者类中用静态代码块想管理类注册自己(这样只需要Class.forName("xxx")就可以执行xxx里的静态内容了,对应到提供者类中就是实例化自身,放在管理类的map中去管理),还有一个管理类,作为服务调用方,主要就和这个管理类打交道,这个类用了一个ConcurrentHashMap集合来维护这些提供者信息,ConcurrentHashMap是一个线程安全的map,具体请自行百度,当有服务提供者注册时就put一个进去,当有调用方调用服务时就get一个出来,也就是key value的操作。
很简单吧~
再看看jdbc是怎么操作的。
Class.forName("com.mysql.jdbc.Driver");
这里的Driver就是我们的提供者类。负责提供Connection(服务)的
Connection connection= DriverManager.getConnection("jdbc:mysql:///xxx", "root", "root");
这里的DriverManager对应提供者管理类,它对外提供一个获取服务(也就是Connection)的方法。
jdbc:mysql说明这个服务提供者是MySQL的,那么从集合(这里用的不是map,是一种list数组集合,可以看看DriverManager类的源码)里取出实现MySQL数据库连接的服务提供者,调用服务提供者的获取服务方法(前文说过,服务提供者肯定有一个获取服务的方法),然后返回我们需要的服务,也就是Connection对象
完~
effective java笔记之java服务提供者框架的更多相关文章
- 转 Java笔记:Java内存模型
Java笔记:Java内存模型 2014.04.09 | Comments 1. 基本概念 <深入理解Java内存模型>详细讲解了java的内存模型,这里对其中的一些基本概念做个简单的笔记 ...
- java 笔记(4) —— java I/O 流、字节流、字符流
Java中使用流来处理程序的输入和输出操作,流是一个抽象的概念,封装了程序数据于输入输出设备交换的底层细节.JavaIO中又将流分为字节流和字符流,字节流主要用于处理诸如图像,音频视频等二进制格式数据 ...
- Java笔记:Java集合概述和Set集合
本文主要是Java集合的概述和Set集合 1.Java集合概述 1)数组可以保存多个对象,但数组长度不可变,一旦在初始化数组时指定了数组长度,这个数组长度就是不可变的,如果需要保存数量变化的数据,数组 ...
- Java笔记:Java 流(Stream)、文件(File)和IO
更新时间:2018-1-7 12:27:21 更多请查看在线文集:http://android.52fhy.com/java/index.html java.io 包几乎包含了所有操作输入.输出需要的 ...
- 菜鸡的Java笔记 简单JAVA 类的开发原则以及具体实现
/* 现在要求定义一个雇员信息类 在这个类之中包含有雇员编号 姓名 职位 基本工资 佣金等信息 对于此时给定要求实际上就是描述一类事物,而这样的程序类在在java之中可以将其称为简单java类 ...
- java笔记--理解java类加载器以及ClassLoader类
类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...
- 疯狂java笔记(七) - Java集合之Map
Map是以键值对(key-value)的形式来存储数据的.而且Map不允许key的重复,通过Map存储key-value对时,只需要考虑key的存储就可以,key存储后value就会跟着key(完全可 ...
- java笔记 chapter1 java是什么,能干什么,有什么,特点,开发环境
一,java是什么 二,java能干什么 三,java有什么 四,java的特点 五,java的三大特性:虚拟机,垃圾回收和代码安全 六,构建JSE开发环境:下载安装jdk和配置环境变量 七,编写并运 ...
- Java笔记 #05# Java Native Interface
参考资料:http://www.ntu.edu.sg/home/ehchua/programming/java/javanativeinterface.html(很详细) 看jdk源代码时,经常会看到 ...
随机推荐
- pgjdbc源码分析
一. 源代码目录结构 pgjdbc的源码结构如下图: 那么我们来一一看看各个模块都是做什么的吧. 1 core 该目录是程序的核心模块目录. 这里实现了大部分pgjdbc的基类和接口,例如statem ...
- MyBatis 一、二级缓存和自定义缓存
1.一级缓存 MyBatis 默认开启了一级缓存,一级缓存是在SqlSession 层面进行缓存的.即,同一个SqlSession ,多次调用同一个Mapper和同一个方法的同一个参数,只会进行一 ...
- Python的egg包
1.背景 查看flower的源码,首先看到flower的主程序如下: #!/usr/local/sinasrv2/bin/python2.7 # EASY-INSTALL-ENTRY-SCRIPT: ...
- Java并发之线程管理(线程基础知识)
因为书中涵盖的知识点比较全,所以就以书中的目录来学习和记录.当然,学习书中知识的时候自己的思考和实践是最重要的.说到线程,脑子里大概知道是个什么东西,但很多东西都还是懵懵懂懂,这是最可怕的.所以想着细 ...
- Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: Access denied
装了fedora23后定时关机:sudo shutdown -h +60 弹出如下信息后立刻就关机了: Failed to call ScheduleShutdown in logind, proce ...
- 照虎画猫写自己的Spring——依赖注入
前言 上篇<照虎画猫写自己的Spring>从无到有讲述并实现了下面几点 声明配置文件,用于声明需要加载使用的类 加载配置文件,读取配置文件 解析配置文件,需要将配置文件中声明的标签转换为F ...
- c语言捕捉异常
闲暇之日阅读lua源码,发现原来C语言除goto之外的另一个处理异常的方法.既为setjump longjump两个函数,setjump相当于try,longjump相当于catch.与goto不同的 ...
- react入门到进阶(二)
一.react属性与事件 1.State属性 State,翻译过来是状态的意思,所以它就代表着组件的状态.React把用户界面(UI)当做是状态机,想象它有不同的状态然后渲染这些状态,可以轻松让用户界 ...
- c语言的typedef
一.typedef作用简介 1.作用:给已经存在的类型起一个新的名称 2.使用场合: 1> 基本数据类型 2> 指针 3> 结构体 4> 枚举 5> 指向函数的指针 * ...
- Python之三目运算符
Python语言不像Java.JavaScript等这些语言有类似: 判段的条件?条件为真时的结果:条件为假时的结果 这样的三目运算,但是Python也有自己的三目运算符: 条件为真时的结果 if 判 ...