日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简单工厂 jdk源码解析

發布時間:2024/4/13 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单工厂 jdk源码解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我們看一下簡單工廠在JDK源碼的一些體現,我們看一個比較熟悉的類,Calendar這么一個類,我們找一個getInstance這么一個方法,public static Calendar getInstance(){return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));}我們看一下這個方法,createCalendar后面傳來一些參數,而這個是一個靜態方法,我們進來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;}現在這個方法是private static方法,我們看一下他的具體實現,這里面有一個if判斷,語言國家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);}else就會返回另外一種實現,下面又返回日本的一個實現,所以我們看一下這里面的代碼,我們在看一下VideoFactory原來的一個寫法,那我們會發現這兩個方法是異曲同工的,都是進行簡單的if判斷,然后把對應的子類實現,Calendar也是這么做的,只不過他這里是使用了static方法,他這里并不是考慮Calendar的擴展性,因為現在應該是滿足的,非常簡單這個源碼,我們看一下這個類相關的一個類圖,我們看一下具體的實現,現在Calendar可以看出來,他實現了三個接口,序列號接口,比較還有克隆,下面就是繼承Calendar類的一個子類,Calendar是一個抽象類

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {是abstract,抽象類會是這樣的一個C,頭標后面是一個權限符,鎖打開就是public,點就是默認的default,通過這種方式學習JDK源碼,是非常有效果的,包括我們去學習Spring的一些開源框架,通過UML先對整體有一個認識,這樣有助于我們對源碼和框架結構關系的全局的理解,這里面我們再擴展一個,我們在寫JDBC的時候,JDK來實現的時候,Class.forName("com.mysql.jdbc.Driver");通過Class.forName把mysql的驅動加載進來,那如果寫ORACLE的驅動呢,這里就變成對應的ORACLE的JDBC的jar包,ORACLE的driver類,然后調用DriverManager的getConnection方法,@CallerSensitivepublic 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這里面還是需要通過注冊的,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());}}因為這個可以看出來它是一個for循環,在遍歷注冊的一個驅動,private final static CopyOnWriteArrayList<DriverInfo> registeredDrivers = new CopyOnWriteArrayList<>();并且它是CopyOnWriteArrayList,里面是DriverInfo,初始化的時候他是一個空的,具體是什么時候完成注冊的呢,我們把mysql的驅動增加進來,<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version> </dependency>我們就用5.1.6這個版本,我們就看一下com.mysql.jdbc.Driver這么一個類一旦我們調用Class.forName,開始執行靜態的DriverManager.registeredDriverstatic { 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 DriverManagerthrow new NullPointerException();}println("registerDriver: " + driver); }如果不存在就往里放if(driver != null) {registeredDrivers.addIfAbsent(new DriverInfo(driver, da)); }public boolean addIfAbsent(E e) 這個方法使用了重入鎖, final ReentrantLock lock = this.lock;這里面我們就不深入來講解了,我們主要還是來關注設計模式,講到這些呢,主要是分享JDK源碼中,一些相關的應用,JDK源碼的分析就講到這里,剛剛MYSQL需要擴展一下 我們看一下pom文件,我們把一些開源的項目導入到我們的設計模式當中,拿這些包主要是為了我們看源碼的時候方便一些,把版本聲明也拿過來,這樣這些包就導入進來了,關于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 ILoggerFactorypackage org.slf4j; //抽象產品工廠 public interface ILoggerFactory {//抽象工廠方法public Logger getLogger(String name); }很明顯ILoggerFactory它是一個接口,下面有一個方法,那這個呢是工廠方法,那在后面我們也會講,這里先過去,后面我們學習工廠方法的時候,再單獨來說,然后通過iLoggerFactory.getLogger,因為它是一個接口,肯定有多個實現,LoggerContext//具體工廠實現類 public class LoggerContext extends ContextBase implements ILoggerFactory, LifeCycle { ...//具體工廠方法@Overridepublic final Logger getLogger(final String name) {...} ...這里面我們看一下,傳入的一個name,這里面要返回Logger,這里面對name進行了判斷,很明顯這個方法就是一個簡單工廠方法,根據傳入的入參進行選擇哪個Logger,那這個還是非常簡單的,剛剛也說了,在我們的LoggerFactory里面,既存在了工廠方法,又存在了簡單工廠,所以設計模式在使用的時候,不一定要局限在使用一種,例如這里就是一個組合的使用,這個簡單工廠比較簡單,在很多源碼中也能夠找到他的影子,在前面的JDK,Logback開源框架的,對于學習設計模式的講解呢,我們在閱讀源碼的時候呢,還可以以設計模式的角度,去聚焦源碼,這樣對我們理解源碼也是有益處的

?

總結

以上是生活随笔為你收集整理的简单工厂 jdk源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。