• 如何学习源码


    一、程序员的层次划分(本文只针对学习源码部分)
      1、只关注项目本身,不懂就baidu一下。
      2、除了做好项目,还会阅读和项目有关的技术书籍,看wikipedia。
      3、找一些开源项目看看,大量试用第三方框架,还会写写demo。 (要解决什么问题?如何实现的?)
          最适合看源码的就是,你对完成一个功能感兴趣,所以你想要了解他。
          比如说Mybatis,你想了解他的代码生成机制,自己先去思考,如果是你做,该怎么做,再去看源码。
          再比如说Log4j.打日志的时候是异步的吗?如果我需要把日志打到另外一台机器上,我该怎么做?
          带着这些问题去思考解决方案。那么天底下的源码都是你的老师。千万别东一锤子西一锤子的去瞎看。
      4、阅读基础框架、J2EE规范、Debug服务器内核。
    二、源码学习
    1、Java源码初接触 
      在eclipse中加入jdk源码
      (1)点 “window“-> “Preferences”-> “Java” -> “Installed JRES”;
      (2)此时"Installed JRES"右边是列表窗格,列出了系统中的JRE 环境,选择你的JRE,然后点边上的“Edit...“, 会出现一个窗口(Edit JRE) ;
      (3)选中rt.jar文件的这一项:“C:Javajdk1.5.0_04jrelib t.jar” 点 左边的“+”号展开它(JDK实际安装路径以你的为准);
      (4)展开后,可以看到“Source Attachment:(none)”,点这一项,点右边的按钮“Source Attachment...“,选择你的JDK目录下的 “src.zip”文件;
      (5)一路点“ok”结束。

      可以从JDK的util包开始,也就是我们学的《数据结构和算法》Java版,如List接口和ArrayList、LinkedList实现,HashMap和TreeMap等。
      这些数据结构里也涉及到排序等算法,一举两得。 面试时,考官总喜欢问ArrayList和Vector的区别,你花10分钟读读源码,估计一辈子都忘不了。

      然后是core包,也就是String、StringBuffer等。
      如果你有一定的Java IO基础,那么不妨读读FileReader等类。看看《Java In A Nutshell》,里面有整个Java IO的架构图。
      Java IO类库,如果不理解其各接口和继承关系,则阅读始终是一头雾水。
      Java IO 包,我认为是对继承和接口运用得最优雅的案例。如果你将来做架构师,你一定会经常和它打交道,如项目中部署和配置相关的核心类开发。

    2、Java Web开发源码
      在阅读Tomcat等源码前,一定要有一定的积累。也可以说是比较好的阶梯是:
      (1)写过一些Servlet和JSP代码。注意,不是用什么Struts,它是很难接触到Servlet精髓的。用好Struts只是皮毛。
      (2)看过《Servlet和JSP核心编程》
      (3)看过Sun公司的Servlet规范
      (4)看过http协议的rfc,debug过http的数据包
      如果有以上基础,也不建议你开始读Tomcat源码。在阅读Tomcat源码前,读过Struts源码,Struts源码比WebWork要简单得多。这个框架是可以100%读懂的,至少WebWork我没有100%读懂。
      如果你读过Struts,再开始考虑Tomcat源码阅读吧。
      不过,还是不建议直接读它,先读读onJava网站上的系列文章《How Tomcat Works》吧,它才是Tomcat的最最简易版。
      它告诉你HttpServletRequest如何在容器内部实现的,Tomcat如何通过Socket来接受外面的请求,你的Servlet代码如何被Tomcat容器调用的(回调)。
      学习JSP,一定要研读容器将JSP编译后的Servlet源码。


    3、Java数据库源码阅读
      先读读Sun的JDBC规范。然后编写JDBC的代码。
      如果了解JDBC规范(接口),那么它的实现,JDBC Driver就一定要开始了解,先读读mysql的jdbc驱动,因为它开源、设计优雅。
      在读mysql的JDBC驱动源码时,建议看看mysql的内幕,官方正好有本书《Mysql Internals》。可以知道mysql的JDBC驱动,如何通过socket数据包(connect、query),给这个C++开发的mysql服务器交互的。
      通过上面的阅读,你可以知道,你的业务代码、JDBC规范、JDBC驱动、以及数据库,它们是如何一起协作的。
      如果你了解这些内幕,那么你再学习Hibernate、iBatis等持久化框架时,就会得心应手的。

    4、Java通讯及客户端软件
      推荐即时通讯软件wildfire和Spark。你可以把wildfire理解成MSN服务器,Spark理解成MSN客户端。它们是通过XMPP协议通讯的。
      我之所以推荐它们。是因为:
      (1)XMPP够轻量级,好理解
      (2)学习Socket通讯实现,特别是C/S架构设计
      (3)模块化设计。它们都是基于module的,你既可以了解模块化架构,还可以了解模块化的技术支撑:Java虚拟机的ClassLoader的应用场景。
      (4)Event Driven架构。虽然GUI都是Event驱动的,但Spark的设计尤其优雅

    5、Java企业级应用
      在读Spring源码前,一定要先看看Rod Johnson写的那边《J2EE Design and Development》,它是Spring的设计思路。注意,不是中文版,中文版完全被糟蹋了。

      “为什么要有这样的架构”,“他是什么样子的”,“他是怎么工作的”。

      IoC容器存在的原因在于对象的解耦,简单来说就是我们自己定义我们要怎么去实现对象中调用的接口。我们做的不就是容器嘛(用新的方式来管理类,那就是容器),我们就定义一个读文件的方法,然后把读到的内容用加载器进行加载,然后放在一个容器里面,名字对应Object,然后开始注入了,我们定义了注入类的位置和被注入类的位置(约定优于配置),我们就去容器中获取。

      ApplicationContext ct=new ClassPathXmlApplicationContext("applicationContext01.xml");    ct.getBean("");

      ClassPathXmlApplicationContext这是东东是我们用来读文件的,可以读配置的文件的类不计其数,只取一个分析,足矣。
      ClassPathXmlApplicationContext这个东东,我们可以追踪他的祖先,AbstractXmlApplicationContext、AbstractRefreshableConfigApplicationContext、AbstractRefreshableApplicationContext、AbstractApplicationContext、DefaultResourceLoader、ResourceLoader,这么多类,一般只读第一个和最后一个,老祖先可以知道它的根基,
      public interface ResourceLoader {
          String CLASSPATH_URL_PREFIX = "classpath:";
          Resource getResource(String var1);
          ClassLoader getClassLoader();
           }

      很明显啊,老祖先ResourceLoader 就是干了这么三件事嘛,定义了加载地址,第二,定义了资源加载的方法,第三,定义了类加载器。
      我们来看下一个重要的类吧。那就是getBean()接口提供类。(ctrl+鼠标左键进入)

      public interface BeanFactory {
           String FACTORY_BEAN_PREFIX = "&";
           Object getBean(String var1) throws BeansException;
           <T> T getBean(String var1, Class<T> var2) throws BeansException;
              <T> T getBean(Class<T> var1) throws BeansException;
           Object getBean(String var1, Object... var2) throws BeansException;
           <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
                   boolean containsBean(String var1);
              boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
                   boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
              boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
                  Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
             String[] getAliases(String var1);
      }

      BeanFactory 很明显就是类的工厂。我们的Resource经过ResourceLoader的调和,用ClassLoader加载,最后变成了BeanFactory。这又是一个粗路线了。
      我们想想资源是不是都需要定义和约束,于是有了BeanDefinition,我们需要封装,于是有了各种**wrapper。
      我们再来想想细节吧,比如说循环注入问题,A引用B,B引用A,那么怎么吧,那不是循环插入到爆炸?那么Spring是怎么实现的。
      我们越想越多,越来越有一种感觉就是,也许那么一刻,那些编程大师,那时候也和你一样这样低头沉思。保持这样的思考,画图,擦涂,重构,最后就是一个能和别人说的思想(架构)。
      在读Hibernate源码前,一定要读读Gavin King写的那本《Hibernate in Action》,同时,应该再读读Martin Fowler写的《企业应用架构模式》,它专门谈到持久化框架的设计思路。

      当你觉得这两本书读透了,再去看它们源码吧。 而且,在读源码前,你会发现它们用到很多第三方Jar包,二三十个,你最好把那些Jar包先一个个搞明白。

      说到企业应用,一定会涉及到工作流。读工作流源码,前提是一定要对其理论模型有深入的了解,以及写过一些demo、或做过一些项目。

  • 相关阅读:
    栈的概念
    什么是 JavaConfig?
    数据库连接池的原理。为什么要使用连接池。
    根据你以往的经验简单叙述一下MYSQL的优化
    动态横切
    横切技术
    什么是AOP
    BIO ,NIO ,AIO 有什么区别?
    简述Comparable和Comparator两个接口的区别
    Spring Boot 客户端?
  • 原文地址:https://www.cnblogs.com/wd326150354/p/10852202.html
Copyright © 2020-2023  润新知