private static Calendar createCalendar(TimeZone zone,Locale aLocale)
{
CalendarProvider provider =
LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
.getCalendarProvider();
if (provider != null) {
try {
return provider.getInstance(zone, aLocale);
} catch (IllegalArgumentException iae) {
// fall back to the default instantiation
}
} Calendar cal = null;
/*根据不同的地区来创建不同的日历对象,就好比日历这个工厂,生产着世界上各地区的日历,我需要这个地区日历,我只需要传参数告诉工厂即可,不需要知道日历制作过程和实例的过程*/
if (aLocale.hasExtensions()) {
String caltype = aLocale.getUnicodeLocaleType("ca");
if (caltype != null) {
switch (caltype) {
case "buddhist":
cal = new BuddhistCalendar(zone, aLocale);
break;
case "japanese":
cal = new JapaneseImperialCalendar(zone, aLocale);
break;
case "gregory":
cal = new GregorianCalendar(zone, aLocale);
break;
}
}
}
if (cal == null) {
// If no known calendar type is explicitly specified,
// perform the traditional way to create a Calendar:
// create a BuddhistCalendar for th_TH locale,
// a JapaneseImperialCalendar for ja_JP_JP locale, or
// a GregorianCalendar for any other locales.
// NOTE: The language, country and variant strings are interned.
if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
cal = new BuddhistCalendar(zone, aLocale);
} else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
&& aLocale.getCountry() == "JP") {
cal = new JapaneseImperialCalendar(zone, aLocale);
} else {
cal = new GregorianCalendar(zone, aLocale);
}
}
return cal;
}

                                  Calendar类图

  除了日历类还有JDBC,当我们需要MySQL数据库的驱动时,我们就传MySQL的参数,用Oracle的就传相应的参数。
在写JDBC的时候,JDK来实现的时候,

Class.forName("com.mysql.jdbc.Driver");
 
通过Class.forName把mysql的驱动加载进来,那如果写ORACLE的驱动呢,这里就变成对应的ORACLE的JDBC的jar包,ORACLE的driver类,然后调用DriverManager的getConnection方法,

      @CallerSensitive
public static Connection getConnection(String url)
throws SQLException {
java.util.Properties info = new java.util.Properties();
return (getConnection(url, info,Reflection.getCallerClass()));
}
获取对应的数据库连接,JDBC的过程也是非常简单的,
      //  Worker method called by the public getConnection() methods.
private static Connection getConnection(
String url, java.util.Properties info, Class<?> caller) throws SQLException {
/*
* When callerCl is null, we should check the application's
* (which is invoking this class indirectly)
* classloader, so that the JDBC driver class outside rt.jar
* can be loaded from here.
*/
ClassLoader callerCL = caller != null ? caller.getClassLoader() : null;
synchronized(DriverManager.class) {
// synchronize loading of the correct classloader.
if (callerCL == null) {
callerCL = Thread.currentThread().getContextClassLoader();
}
} if(url == null) {
throw new SQLException("The url cannot be null", "08001");
} println("DriverManager.getConnection(\"" + url + "\")"); // Walk through the loaded registeredDrivers attempting to make a connection.
// Remember the first exception that gets raised so we can reraise it.
SQLException reason = null; for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
println(" trying " + aDriver.driver.getClass().getName());
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
// Success!
println("getConnection returning " + aDriver.driver.getClass().getName());
return (con);
}
} catch (SQLException ex) {
if (reason == null) {
reason = ex;
}
} } else {
println(" skipping: " + aDriver.getClass().getName());
} } // if we got here nobody could connect.
if (reason != null) {
println("getConnection failed: " + reason);
throw reason;
} println("getConnection: no suitable driver found for "+ url);
throw new SQLException("No suitable driver found for "+ url, "08001");
}
通过Class.forName这种方式,直接通过反射拿到对应的Video,只不过MSYQL这里面还是需要通过注册的,
        // Walk through the loaded registeredDrivers attempting to locate someone
// who understands the given URL.
for (DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
if(isDriverAllowed(aDriver.driver, callerClass)) {
try {
if(aDriver.driver.acceptsURL(url)) {
// Success!
println("getDriver returning " + aDriver.driver.getClass().getName());
return (aDriver.driver);
} } catch(SQLException sqe) {
// Drop through and try the next driver.
}
} else {
println(" skipping: " + aDriver.driver.getClass().getName());
} }

因为这个可以看出来它是一个for循环,在遍历注册的一个驱动,
 
private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();
 
并且它是CopyOnWriteArrayList,里面是DriverInfo,初始化的时候他是一个空的,具体是什么时候完成注册的呢,

static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
这个时候就会在registerDriver(new Driver())这个方法里面直接注册这个Driver,那里面的Driver自然就是MySQL的Driver,
public static synchronized void registerDriver(java.sql.Driver driver,

            DriverAction da)

        throws SQLException {

        /* Register the driver if it has not already been added to our list */

        if(driver != null) {

            registeredDrivers.addIfAbsent(new DriverInfo(driver, da));

        } else {

            // This is for compatibility with the original DriverManager

            throw new NullPointerException();

        }

        println("registerDriver: " + driver);

}

如果不存在就往里放

if(driver != null) {

registeredDrivers.addIfAbsent(new DriverInfo(driver, da));

}

此外,logback中也有简单工厂的影子。

public final class LoggerFactory

public static ILoggerFactory getILoggerFactory() {

}

最里面有一个getLogger方法,

public static Logger getLogger(Class clazz) {

return getLogger(clazz.getName());

}

public static Logger getLogger(String name) {

ILoggerFactory iLoggerFactory = getILoggerFactory();

return iLoggerFactory.getLogger(name);

}

这个还有个重载,一个是String name,还有一个是Class clazz,clazz是干嘛的,是clazz.getName(),

首先getLogger根据我们传来的name,从iLoggerFactory里面getLogger,先看一下

public interface ILoggerFactory   

  package org.slf4j;

  //抽象产品工厂

  public interface ILoggerFactory {

     //抽象工厂方法

      public Logger getLogger(String name);

 }

很明显ILoggerFactory它是一个接口,下面有一个方法,那这个呢是工厂方法,那在后面我们也会讲,这里先过去,

后面我们学习工厂方法的时候,再单独来说,然后通过iLoggerFactory.getLogger,因为它是一个接口,肯定有多个实现,

  LoggerContext   

  //具体工厂实现类

  public class LoggerContext extends ContextBase implements ILoggerFactory, LifeCycle {

  ...

      //具体工厂方法

      @Override

      public final Logger getLogger(final String name) {

       ...

      }

这里面我们看一下,传入的一个name,这里面要返回Logger,这里面对name进行了判断,很明显这个方法就是一个简单工厂方法,

根据传入的入参进行选择哪个Logger,那这个还是非常简单的,刚刚也说了,在我们的LoggerFactory里面,既存在了工厂方法,

又存在了简单工厂,所以设计模式在使用的时候,不一定要局限在使用一种,例如这里就是一个组合的使用,这个简单工厂比较简单,

在很多源码中也能够找到他的影子,在前面的JDK,Logback开源框架的,对于学习设计模式的讲解呢,我们在阅读源码的时候呢,

还可以以设计模式的角度,去聚焦源码,这样对我们理解源码也是有益处的 。

简单工厂(三)——JDK源码中的简单工厂的更多相关文章

  1. 结合JDK源码看设计模式——简单工厂、工厂方法、抽象工厂

    三种工厂模式的详解: 简单工厂模式: 适用场景:工厂类负责创建的对象较少,客户端只关心传入工厂类的参数,对于如何创建对象的逻辑不关心 缺点:如果要新加产品,就需要修改工厂类的判断逻辑,违背软件设计中的 ...

  2. 设计模式-简单工厂Coding+jdk源码解析

    感谢慕课geely老师的设计模式课程,本套设计模式的所有内容均以课程为参考. 前面的软件设计七大原则,目前只有理论这块,因为最近参与项目重构,暂时没有时间把Coding的代码按照设计思路一点点写出来. ...

  3. JDK源码中,都有哪些NB的设计模式?

    转载:https://mp.weixin.qq.com/s/h88UxB9F2MkTbHqck3KQiQ 一.结构性模式: 1.适配器模式: 常用于将一个新接口适配旧接口 肥朝小声逼逼:在我们业务代码 ...

  4. Java1.8 JDK源码中,对两个类进行 按位与 操作是什么意思

    Java容器类库中的Map接口(java\util\Map.java)中有一个Entry接口(java\util\Map.java),其中有几个接口方法用到了类和类的按位与操作,即类和类之间有 &am ...

  5. JDK源码中使用的设计模式

    结构型模式: 适配器模式: 用来把一个接口转化成另一个接口. java.util.Arrays#asList() javax.swing.JTable(TableModel) java.io.Inpu ...

  6. JDK源码中的英文注释翻译(Enum<E extends Enum<E>>)

    public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializab ...

  7. JDK源码中的英文注释翻译(Class)

    public final class Class<T> implements java.io.Serializable, GenericDeclaration, Type, Annotat ...

  8. 关于JDK源码:我想聊聊如何更高效地阅读

    简介 大家好,我是彤哥,今天我想和大家再聊聊JDK源码的几个问题: 为什么要看JDK源码 JDK源码的阅读顺序 JDK源码的阅读方法 为什么要看JDK源码 一,JDK源码是其它所有源码的基础,看懂了J ...

  9. Java设计模式:23种设计模式全面解析(超级详细)以及在源码中的应用

    从网络上找的设计模式, 很全面,只要把UML类图看懂了, 照着类图将代码实现是很容易的事情. 步骤: 先看懂类图, 然后将代码实现, 之后再看文字 http://c.biancheng.net/des ...

随机推荐

  1. _IplImage

    IplImage结构 由于OpenCV主要针对的是计算机视觉方面的处理,因此在函数库中,最重要的结构体是IplImage结构.从本质上讲,他是一个CvMat对象,但它还有一些其他成员变量将矩阵解释为图 ...

  2. 客户端本地存储,web存储,localStorage

    HTML5 LocalStorage 本地存储 说到本地存储,这玩意真是历尽千辛万苦才走到HTML5这一步,之前的历史大概如下图所示: 最早的Cookies自然是大家都知道,问题主要就是太小,大概也就 ...

  3. UI系统的分类

    1.DSL系统:UI领域特定语言 html markdown; 与平台无关,只与通用UI领域有关: 2.平台语言系统(通用语言系统) UI概念在平台和通用语言中的表示. 一.信息表达: 基本信息:文本 ...

  4. Docker报错“Dockerfile parse error line 1: FROM requires either one or three arguments”

    看官方文档Format: 以 '#' 开头一行被视为评论,出现在其他位置视为参数. 也就不难理解报错原因:将写在同一行的注释视为参数了. 原Dockerfile: 改为:

  5. MongoDB索引存储BTree与LSM树(转载)

    1.为什么 MongoDB 使用B-树,而不是B+树 MongoDB 是一种 nosql,也存储在磁盘上,被设计用在数据模型简单,性能要求高的场合.性能要求高,我们看B-树与B+树的区别: B+树内节 ...

  6. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  7. K8s的存储卷使用总结

    K8s的存储卷: 它有四种存储卷: 1. emptyDir: 空目录,这种存储卷会随着Pod的删除而被清空,它一般作为缓存目录使用,或临时目录, 当做缓存目录时,通常会将一块内存空间映射到该目录上,让 ...

  8. nginx 访问控制之 http_referer

    在rewrite时,曾经用过该变量,当时实现了防盗链功能. 其实基于该变量,我们也可以做一些特殊的需求. 示例: 背景:网站被黑挂马,搜索引擎收录的网页是有问题的,当通过搜索引擎点击到网站时,却显示一 ...

  9. nginx rewrite实战实例

    本部分内容为nginx生产环境中使用的场景示例. 域名跳转(域名重定向) 示例1(不带条件的): server{ listen ; server_name www.aminglinux.com; re ...

  10. TensorFlow 报错 ValueError: Can't load save_path when it is None.

    原因 : 模型还未生成出来 , 此时你去检测的生成完毕的模型 , 模型呢 ? 还没生成 . 模型还没生成就引用了为什么不报错 ? 解决办法 : 当前情况不要以为是你的程序有 bug , 而是你的模型还 ...