Java新人上(li)

同等、项目蒙选配使用SVN和Git

  安装SVN;安装熟悉Git;安装maven,修改setting.xml文件;安装eclipse,配置jdk、maven路径;

  建立协调的Git仓库,熟悉常用之Git命令。熟识基本Linux命令。ssh登录线上环境,查看日志。

// #拷贝并跟踪远程的master分支。跟踪的好处是以后可以直接通过pull和push命令来提交或者获取远程最新的代码,而不需要指定远程分支名字
// git clone

//#创建名为branchName的branch
//git brach branchName  

//#切换到branchName的branch
//git checkout branchName  

老二、项目启动(antx、Autoconfig、JVM参数)

  antx中部分部署起依赖让本机环境,要做出修改。antx.properties文件之企图存储所有placeholders的价值,作为AutoConfig的输入,使配置与代码隔离。当更换环境时单待更改antx.properties,方便集中式管理有变量,让同样模拟代码适用多个条件。

  于一个类别中,总会生局部参数在开发环境及生育条件是见仁见智之,或者会冲环境的转变而生成。我们只要由此硬编码的章程,势必要经常性的改动项目代码。那咱们得据此同一栽艺术,在品种编译前以可换的参数改吗可部署的。如此,灵活性就大大的加码,也抽了时修改代码可能带来的无平静风险。Autoconfig就是这样的一个工具,它经过占位符将需要动态配置的情替换。核心思想是拿有可变的部署定义也一个模板,在autoconfig运行的时段打这些模板被生成具体的配备文件。AutoConfig不需要取源码,也不需再行build,即可改变目标文件被有所配置文件中placeholders的价值,AutoConfig可以对placeholder及其值进行自我批评。

图片 1

  说下:autoconfig为什么不需领取源码就足以改变目标文件被的待替换值。观察Ali-Tomcat的启动流程,我们好窥见,Ali-Tomcat在Tomcat基本组件启动了之后,部署项目事先会还去找寻项目受到的auto-config.xml文件,然后就对placeholder的再度替换,autoconfig的这种优势是依靠于Ali-Tomcat的,从服务器的起步日志就可以看出。上图为Ali-Tomcat的启动日志。

参数名称 含义 默认值  
-Xms 初始堆大小 物理内存的1/64(<1GB) 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制.
-Xmx 最大堆大小 物理内存的1/4(<1GB) 默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制
-Xmn 年轻代大小(1.4or lator)   注意:此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是不同的。
整个堆大小=年轻代大小 + 年老代大小 + 持久代大小.
增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8
-XX:NewSize 设置年轻代大小(for 1.3/1.4)    
-XX:MaxNewSize 年轻代最大值(for 1.3/1.4)    
-XX:PermSize 设置持久代(perm gen)初始值 物理内存的1/64  
-XX:MaxPermSize 设置持久代最大值 物理内存的1/4  
-Xss 每个线程的堆栈大小   JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K.更具应用的线程所需内存大小进行 调整.在相同物理内存下,减小这个值能生成更多的线程.但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右
一般小的应用, 如果栈不是很深, 应该是128k够用的 大的应用建议使用256k。这个选项对性能影响比较大,需要严格的测试。(校长)
和threadstacksize选项解释很类似,官方文档似乎没有解释,在论坛中有这样一句话:"”
-Xss is translated in a VM flag named ThreadStackSize”
一般设置这个值就可以了。
XX:ThreadStackSize Thread Stack Size   (0 means use default stack size) [Sparc: 512; Solaris x86: 320 (was 256 prior in 5.0 and earlier); Sparc 64 bit: 1024; Linux amd64: 1024 (was 0 in 5.0 and earlier); all others 0.]
-XX:NewRatio 年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)   -XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。
-XX:SurvivorRatio Eden区与Survivor区的大小比值   设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
-XX:LargePageSizeInBytes 内存页的大小不可设置过大, 会影响Perm的大小   =128m
-XX:+UseFastAccessorMethods 原始类型的快速优化    
-XX:+DisableExplicitGC 关闭System.gc()   这个参数需要严格的测试
-XX:MaxTenuringThreshold 垃圾最大年龄   如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代. 对于年老代比较多的应用,可以提高效率.如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活 时间,增加在年轻代即被回收的概率
该参数只有在串行GC时才有效.
-XX:+AggressiveOpts 加快编译    
-XX:+UseBiasedLocking 锁机制的性能改善    
-Xnoclassgc 禁用垃圾回收    
-XX:SoftRefLRUPolicyMSPerMB 每兆堆空闲空间中SoftReference的存活时间 1s softly reachable objects will remain alive for some amount of time after the last time they were referenced. The default value is one second of lifetime per free megabyte in the heap
-XX:PretenureSizeThreshold 对象超过多大是直接在旧生代分配 0 单位字节 新生代采用Parallel Scavenge GC时无效
另一种直接在旧生代分配的情况是大的数组对象,且数组中无外部引用对象.
-XX:TLABWasteTargetPercent TLAB占eden区的百分比 1%  
-XX:+CollectGen0First FullGC时是否先YGC false  

  JVM性能调优过程,也便是修改上述参数的安排文件,如下图所显示,永久代的内存不够,需要增大PermGen的上空,进行
jvm 参数设置:-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256M
-Dfile.encoding=UTF-8。JVM各参数的含义达成图。

三、maven学习

  什么是pom,pom作为项目对象模型。通过xml表示maven项目,使用pom.xml来贯彻。POM包括了装有的花色信息:groupId:项目或组织的唯一标志,并且配备时生成路径也是经过生成,如org.myproject.mojo生成的相对路径为:/org/myproject/mojo。artifactId:项目之通用名称。version:项目之本子。packaging:打包机制,如pom,jar,maven-plugin,ejb,war,ear,rar,par。

  pom继承关系:要延续pom就待发一个父pom,在Maven中定义了最佳pom.xml,任何没有说明自己父pom.xml的pom.xml都将默认继承自是超级pom.xml。(项目分别)子pom.xml会全盘继承父pom.xml中具有的要素,而且于同一的元素,一般子pom.xml中之会盖父pom.xml中之因素,但是有几乎单与众不同之要素它们会进展统一而休是掩。这些特别之素是:dependencies,developers,contributors,plugin列表,resources。当得继续指定的一个Maven项目时,我们要以融洽的pom.xml中定义一个parent元素,在是元素中指明要后续项目的groupId、artifactId和version。当被延续项目与持续项目之目录结构不是父子关系的时刻,这个时便得在子项目之pom.xml文件定义着的parent元素下还长一个relativePath元素的概念,用以描述父项目的pom.xml文件相对于子项目之pom.xml文件之职。

  pom聚合关系:说说我对聚集和为集的解,比如说如果projectA聚合到projectB,那么我们就足以说projectA是projectB的子模块,
projectB是叫集项目,也可接近于继续那样称为大项目。对于聚合而言,这个中心应当是吃集的色。所以,我们用以让集结的种蒙定义其的子模块,而未是如继承那样在子项目遭到定义父项目。具体做法是:修改被集结项目之pom.xml中之packaging元素的价也pom;在被凑项目之pom.xml中之modules元素下指定它的子模块项目。如果实模块projectB是处于被凑项目projectA的子目录下,即和被集结项目之pom.xml处于同一目录。这里以的module值是分段模块projectB对应的目录名projectB,而非是子模块对应之artifactId。这个时候当我们针对projectA进行mvn
package命令时,实际上Maven也会指向projectB进行包装。当给凑项目与子模块项目在目结构及无是父子关系的时,需要在module元素中指定为相对路径的办法指定子模块。以plutus-web根目录下之pom为例:

图片 2

专注:如果出A,B,C三个子工程,并且install的依次是A,B,C,这样使是A依赖B的言辞,执行mvn
clean install必然报错,因为install
A的下,B还从来不成形,所以我们在描写modules的时候自然要留意顺序。如果projectB继承projectA,同时用拿projectB聚合到projectA,projectA的pom.xml中得定义其的packaging为pom,需要定义其的modules,同时以projectB的pom.xml文件被新增一个parent元素,用以定义其延续的花色信息。

  pom依赖关系,项目里面的借助是经pom.xml文件中的dependencies元素下面的dependency元素进行的。一个dependency元素定义一个依靠关系。在dependency元素中我们第一透过依赖型之groupId、artifactId和version来定义所依赖之项目。

  setting.xml一般存在和片独地方:maven的设置目录/conf/,和/.m2/下。他们之界别是于maven安装目录下之setting.xml是具备用户还足以以的配备,而user.home下之是针对性某平等用户之部署(推荐是在user.home下)。如果少只都进展了配备,则当应用之时段会将有限单布局文件进行和,而且user.home下之setting.xml优先级大于maven安装目录下之。

  maven中之snapshot快以仓库,maven中的库分为两栽,snapshot快本仓库和release发布仓库。snapshot快以仓库用于保存开发进程中的莫平静版本,release正式仓库则是故来保存稳定的批发本。在用maven过程遭到,我们以开发阶段经常性的会面生好多公共库处于无稳定状态,随时需要修改并披露,可能同样上就是假设颁发一不良,遇到bug时,甚至同一天要发布N次。maven的赖管理是冲版本管理的,对于公布状态的artifact,如果版本号相同,即使我们中的镜像服务器上的机件比当地新,maven也非会见再接再厉下载的。如果我们当开发阶段都是基于专业颁发版来开依赖管理,那么遇到这问题,就待提升组件的本号,可这么虽明摆着不符合要求和实在状况了。如果是因快照版本,那么问题即自热而然的化解了,maven2会根据模块的版本号(pom文件被的version)中是否带有-SNAPSHOT来判断是快照版本要正式版本。如果是快照版本,那么当mvn
deploy时会见自行发布暨快照版本库中,而动快照版本的模块,在无重改版本号的状况下,直接编译打包时,maven会自动从镜像服务器上下载最新的快照版本。如果是正经颁发版,那么在mvn
deploy时见面自动宣布到正式版本库中,而以专业版本的模块,在不更改版本号的景象下,编译打包时只要当地曾经存在拖欠本的模块则未会见主动去镜像服务器上下载。所以,我们当开发阶段,可以拿公用库的版设置也快照版本,而被依组件则引述快照版本进行付出,在公用库的快照版本更新后,我们为无欲改pom文件提示版本号来下充斥新的版本,直接mvn执行有关编译、打包命令即可重新下载最新的快照库了,从而为有益了俺们开展开。

  maven的决策机制。maven自己之决策机制是预先看路长度,路径长度一样再次看声明顺序。

四、Socket

  socket,通常也叫”套接字”,用于描述IP地址及端口,是网及运行的有限个次中双向通讯的单,它既是好承受请求,也可发送请求,利用它可以比较有利的编网络直达之数据的传递。Socket通讯过程:服务端监听某个端口是否有连日要,客户端向服务端发送连接要,服务端收到连接要于客户端有接收信息,这样一个连连就建立起来了。客户端和服务端都得以相互发送信息及对方展开报道。

  Socket编程中之根本艺术,Accept方法用于产生”阻塞”,直到接受到一个老是,并且返回一个客户端的Socket对象实例。getInputStream方法得到网络连接输入,即一个输入流,同时返回一个IutputStream对象实例,客户端的Socket对象及之
getInputStream方法赢得的输入流其实就是自从劳动器端发回之数据流;服务器端的输入流就是经受客户端发来的数据流。getOutputStream方法实现一个输出流,同时返回一个OutputStream对象实例。客户端的输出流就是即将发送至服务器端的数据流,服务器端的输出流就是发给客户端的数据流。注意:getInputStream和getOutputStream方法皆会产生一个IOException,它必须被抓走;getInputStream和getOutputStream方法返回的是流对象,通常还见面给另外一个流对象使用。所以还要对当时片种植方式取得的数量进行包装,以便更便利之运用。

  单线程代码有一个题目,就是Server只能承受一个Client请求,当第一单Client连接后即使占据了这位置,后续Client不可知再累连接。所以用举行来改动,当Server每接受到一个Client连接要后,都把拍卖流程放到一个独门的线程里去运转,然后等待下一个Client连接要,这样虽未会见阻塞Server端接收请求了。每个独立运转的次序于以完Socket对象下如果拿其倒闭。改进后底代码同样以点的git地址。

五、并作编程学习(线程之间的排外和协同)

  synchronized锁重入,关键字synchronized拥有锁重入的功用。也即是在运synchronized时,当一个线程得到一个对象锁后,再次呼吁是目标锁经常,是好另行赢得该目标的缉的。所以在一个synchronized方法/块的里边调用本类的另外synchronized方法/块常,是永恒可以博锁之。可还称锁就是是温馨可以还取得自己之中锁,当是父子类继承关系经常,子类是一点一滴可以经过“可另行入锁”调用父类的同方法的。

  synchronized同步语句块,对另synchronized同步方法还是synchronized(this)同步代码块调用呈阻塞状态。同一时间只生一个线程可以实行synchronized同步方法被之代码。

  synchronized(非this对象x),当多只线程同时实施synchronized(x){}同步代码块常呈同步效果;当其他线程执行x对象被synchronized同步方法时呈同步效果;当其他线程执行x对象方法中的synchronized(this)代码块常为显现同步效果;但是若另外线程调用不加synchronized关键字的点子时,还是异步调用。

  synchronized以及volatile比较,volatile性能比synchronized要好,并且volatile只能修饰于变量,而synchronized可以修饰方法,以及代码块。多线程访问volatite不会发生堵塞,而synchronized会冒出堵塞。volatite能保证数据的可见性,但切莫可知管原子性;而synchronized可以保证原子性,也可以间接保证可见性,因为她会用民用内存和官内存中的多寡做并。volatite解决之是变量在差不多个线程之间的可见性;而synchronized关键字解决之是多只线程之间访问资源的同步性。volatite提示线程每次从共享内存中读取变量,而无是由个人内存中读取,这样尽管保险了伙同数据的可见性。

  Lock接口最充分之优势是为念与描写分别提供了锁,读写锁ReadWriteLock拥有更加强的功力,它可是划分为读锁和写锁。读锁得允许多独进行读操作的线程同时上,但切莫允写进程上;写锁就允许一个写进程上,在当下中间任何进程都无克还进来。

  ReentrantLock是一个可重入的排挤锁
Lock,它拥有与下 synchronized
方法与语句所访问的隐式监视器锁相同的局部核心行为和语义,但力量又有力。ReentrantLock
将由多年来打响收获锁,并且还无放该锁的线程所享有。当锁没有给另外一个线程所具备时,调用lock的线程将不负众望获得该锁并返。如果手上线程已经拥有该锁,此办法将即刻回。可以利用isHeldByCurrentThread()和getHoldCount()方法来检查是景是否来。

  Condition
将Object监视器方法(wait、notify 和
notifyAll)分解成了不同的靶子,以便通过以这些目标和任意 Lock
实现做以,为每个对象提供多独待集合。其中,Lock 替代了 synchronized
方法以及言语的用,Condition 替代了 Object
监视器方法的以。**
Condition实例实质上受绑定到一个沿上。要为特定Lock实例获得Condition实例,请动该newCondition()方法。**

  ReentrantReadWriteLock,可又称读写锁。它实现ReadWriteLock接口,此沿允许
reader 和 writer 按照 ReentrantLock
的体制重新赢得读取锁或写副锁。在描写副线程保持的有着写副锁都已经放后,才允许重入
reader
使用它们。锁降级:重入还同意打写副锁降级为念取锁,其实现方式是:先获得写入锁,然后抱读取锁,最后放写副锁。但是,从读取锁升级到写副锁是休可能的。它对Condition的支持。写副锁提供了一个
Condition 实现,对于刻画副锁吧,该兑现的作为及
ReentrantLock.newCondition() 提供的 Condition 实现对 ReentrantLock
所开的表现等同。当然,此 Condition 只能用来形容副锁。读取锁不支持
Condition,readLock().newCondition() 会抛来
UnsupportedOperationException。

六、线程间的通信

  wait()方法,wait()的打算是如目前推行代码的线程进行等待,当前线程释放锁。调用之前线程必须获得该目标的对象锁。

  notify()方法,不见面要当前线程马上放对象锁,呈wait()状态的底线程也不能够即时得该目标的对象锁,要当及实施notify()方法的线程将程序执行完,退出synchronized代码块后才见面释放锁。

  notifyALL()方法,可以假设有正在等待队列中等待同意共享资源的整线程从等待状态退出,进入但运行状态。

  wait和sleep方法的异,这点儿独主意来不同之近乎分别是,sleep来自Thread类静态方法,和wait来自Object类成员方法。(sleep是Thread的静态类方法,谁调用的哪个去睡觉,即使在a线程里调用了b的sleep方法,实际上还是a去睡觉,要吃b线程睡觉要于b的代码中调用sleep。)最要害是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以运用同步控制块或措施。(sleep不闹为系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占CPU。一般wait不会见加日范围,因为若wait线程的运转资源不够,再出来啊并未因此,要待其他线程调用notify/notifyAll唤醒等待池中之具备线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以据此时指定要她自动提醒过来,如果日不交只能调用interrupt()强行打断。)Thread.Sleep(0)的图是“触发操作系统立刻又开展同样赖CPU竞争”。使用范围:wait,notify和notifyAll只能够当同步控制方法还是同步控制块里面用,而sleep可以以其他地方使用。sleep必须捕获异常(InterruptedException),而wait,notify和notifyAll不欲捕获异常。总结:最老之差是以伺机时wait会释放锁,而sleep一直有锁。Wait通常被用来线程间相互,sleep通常给用于暂停实施。

  join()的意是一旦所属的线程对象x正常执行run()方法中的任务,而如果目前线程z进行无限期的隔阂,等待线程x销毁后又继续执行线程z后面的代码。方法join具有使线程排队运行的打算类似于同的运行效果。join与synchronized的分别是:join在里面以wait()方法开展等待(所以有释放锁的特点),而synchronized关键字下的是“对象监视器”原理作为联合。

  生产者消费者,操作栈List实现,List最深容量是1,解决wait条件转与假死,多生产者多顾客实现。

七、线程池

  为什么使用线程池?线程启动一个初线程的血本是于大的,因为它事关与操作系统交互,在这种场面下,使用线程池可以生好的增长性,尤其是当次中需要创造大气生存期很短暂的线程时,更应当考虑使用线程池。线程池在系统启动时即创建大气空暇的线程,程序将一个Runnable对象传给线程池,线程池就会见启动同条线程来实行该目标的run()方法,当run()方法执行完毕后,该线程并无会见死亡,而是重返回线程池中变为空闲状态,等待执行下一个Runnable对象的run方法。使用线程池可以有效地控制体系面临并发线程的数码,当系统受到带有大量连发线程时,会导致系统性能剧烈下跌,甚至造成JVM崩溃,而线程池的极其充分线程数参数可以决定体系面临连发线程数目不超过此数。

  ThreadPoolExecutor重要参数,corePoolSize:核心池的轻重缓急,这个参数与后讲述的线程池的实现原理来大充分的涉。在创造了线程池后,默认情况下,线程池中连没任何线程,而是等有任务来才创建线程去履行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从当时2独艺术的名字就可以看出,是先行创建线程的意思,即在并未任务赶来前即创造corePoolSize个线程或者一个线程。默认情况下,在创造了线程池后,线程池中的线程数为0,当有任务来之后,就见面创造一个线程去实施任务,当线程池中之线程数目及corePoolSize后,就见面把到的职责放到缓存队列中。maximumPoolSize:线程池最充分线程数,这个参数为是一个良关键之参数,它表示在线程池中极度多克创造多少个线程。keepAliveTime:表示线程没有任务履行时最好多维持多久年华会终止。默认情况下,只有当线程池中之线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不盖corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲之时刻达keepAliveTime,则会停,直到线程池中的线程数不超corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中之线程数不超越corePoolSize时,keepAliveTime参数为会见从作用,直到线程池中之线程数为0。

  对参数的村办了解:如果手上线程池中之线程数目小于corePoolSize,则每来一个职责,就见面创造一个线程去实践之任务。当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试以其上加到任务缓存队列中,若添加事业有成,则该任务会等待空闲线程将那个获取出来执行;若加上失败(一般的话是任务缓存队列已满),则会尝试创建新的线程去履行是职责。如果手上线程池中之线程数目及maximumPoolSize,则会使用任务拒绝策略进行拍卖。如果线程池中之线程数量过
corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将让停,直至线程池中之线程数目不超越corePoolSize;如果允许吗核心池中的线程设置存活时间,那么核心池中之线程空闲时间超过keepAliveTime,线程也会见叫终止。

  ThreadPoolExecutor的显要措施,execute()方法其实是Executor中宣称的办法,在ThreadPoolExecutor进行了具体的实现,这个法子是ThreadPoolExecutor的主导措施,通过此办法可向线程池提交一个任务,交由线程池去实践。submit()方法是于ExecutorService中扬言的法,在AbstractExecutorService就早已起了切实可行的落实,在ThreadPoolExecutor中并没针对那个进行重写,这个方式呢是故来为线程池提交任务的,但是其与execute()方法不同,它亦可回到任务尽之结果,去看submit()方法的实现,会发现她实在要调用的execute()方法,只不过它利用了Future来赢得任务履行结果。shutdown()和shutdownNow()是因此来关闭线程池的。

// #shutdown()和shutdownNow()区别:
// shutdown():不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务
// shutdownNow():立即终止线程池,并尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务

  BlockingQueue,阻塞队列(BlockingQueue)是一个支持少数个叠加操作的班。这有限单附加的操作是:在群列为空时,获取元素的线程会等待队列化非空。当行满时,存储元素的线程会等待队列可用。
阻塞队列常用于生产者与消费者之面貌,生产者是于队列里上加元素的线程,消费者是从队列里以元素的线程。阻塞队列就是劳动者存放元素的器皿,而顾客也仅于容器里将元素。用wait和notify实现阻塞队列;用ReentrantLock实现阻塞队列。

  静态方法上synchronzied和免静态方法上synchronized关键字的区分是什么?在运synchronized块来齐方法时,非静态方法可以透过this来共,而静态方法必须采取class对象来一块,非静态方法也堪通过动用class来一同静态方法。但是静态方法中无可知以this来和步非静态方法。这点在使用synchronized块用专注。synchronized是对类的当前实例进行加锁,防止其他线程同时做客该类的欠实例的有着synchronized块,注意这里是“类的即实例”,
类的鲜个不同实例就没这种约束了。static
synchronized是一旦控制类的拥有实例的拜访了,static
synchronized是限制线程同时做客jvm中此类的所有实例同时做客对应的代码块。在类似中之一艺术要某代码块中生出
synchronized,那么在转一个此类实例后,该类也就算有一个监视块,放置线程并发访问该实例synchronized保护块,而static
synchronized则是颇具此类的实例公用一个监块了,也也即是鲜单的区分了,也便是synchronized相当给
this.synchronized,而static
synchronized相当给Something.synchronized。

八、spring

九、MyBatis

  MyBatis要高达目的就是是把用户关心的同容易变之数放到配置文件被安排,方便用户管理。而将流程性的、固定不移的交ibatis来兑现。这样是用户操作数据库简单、方便。以前用jdbc有好多操作是暨事务以及数据无关之,但我们只是需要一个运转sql语句之法力,还有取回结果的机能,但是jdbc要求您处理连接、会话、statement,尤其是还要你注意关闭资源,还要写try
catch处理好。ibatis 就是赞助您管这些乱七八糟的东西还开了。ibatis通过 SQL
Map将Java对象映射成SQL语句和以结果集还转发成Java对象,与任何ORM框架相比,既解决了Java对象同输入参数与结果集的照耀,又会为用户方便之手写以
SQL语句。

//#总结起来有一下几个优点:
//ibatis把sql语句从Java源程序中独立出来,放在单独的XML文件中编写,给程序的维护带来了很大便利。
//ibatis封装了底层JDBC API的调用细节,并能自动将结果集转换成Java Bean对象,大大简化了Java数据库编程的重复工作。
//因为ibatis需要我们自己去编写sql语句,程序员可以结合数据库自身的特点灵活控制sql语句,因此能够实现比hibernate等全自动orm框架更高的查询效率,能够完成复杂查询。相对简单易于学习,易于使用, 非常实用。

  Mybatis原理,该框架的一个重点部分就是彼
SqlMap 配置文件,SqlMap 配置文件的为主是 Statement 语句包括 CIUD。
MyBatis通过分析 SqlMap 配置文件得到有的 Statement 执行语句,同时会形成
ParameterMap、ResultMap 两个目标用于拍卖参数和透过分析后提交数据库处理的
Sql 对象。这样除了数据库的连年,一久 SQL
的推行标准既颇具了。数据的照射大体的经过是这么的:根据 Statement
中定义的 SQL 语句,解析出里面的参数,按照其冒出的逐一保存在 Map
集合中,并据 Statement 中定义的 ParameterMap 对象类型解析出参数的 Java
数据类型。并冲该数据类型构建 TypeHandler 对象,参数值的复制是经过
DataExchange 对象好的。

public class Test {
    public static void main(String[] args) {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection conn = DriverManager.getConnection(url, user, password);
        java.sql.PreparedStatement st = conn.prepareStatement(sql);
        st.setInt(0, 1);
        st.execute();
        java.sql.ResultSet rs = st.getResultSet();
        while (rs.next()) {
            String result = rs.getString(colname);
        }
    }
}

上述代码展现了旧的java操作数据库的代码,Mybatis就是以方面这几乎尽代码分解包装。但是最终实施之依然是立几乎实行代码。前少推行是指向数据库的数据源的保管包括事务管理,3、4
两执行ibatis通过配备文件来治本 SQL 以及输入参数的投,6、7、8 行是 iBATIS
获取返回结果到 Java 对象的照射,他也是经安排文件管理。

  spring和Mybatis的事情机制,MyBatis的SqlMapSession
对象的创办和释放根据不同情形会产生不同,因为 SqlMapSession
负责创建数据库的连续,包括对事情之管理,iBATIS
对保管工作既好团结管理为可由外部管理,iBATIS 自己管理是通过共同享
SqlMapSession 对象实现之,多个 Statement 的推行时共享一个 SqlMapSession
实例,而且都是线程安全之。如果是外部程序管理就设团结说了算 SqlMapSession
对象的生命周期。

  spring对事情之解决办法其实分为2种:编程式实现工作,AOP配置声明式解决方案。spring提供了众多停放事务管理器实现,对于ibatis是DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供针对性单个javax.sql.DataSource事务管理,用于Spring
JDBC抽象框架、iBATIS框架的事务管理。注解形式@Transactional实现事务管理,只能让采取至public方法及,对于其他非public的法门,如果标记了@Transactional也未会见报错,但方法没有工作功能。在public方法方面运用了@Transactional注解,当有线程调用这个方法时,Spring会首先扫描到@Transactional注解,进入DataSourceTransactionManager继承自AbstractPlatformTransactionManager的getTransaction()方法,在getTransaction()方法中,会调用doGetTransaction()方法,@Transactional的诠释中,存在一个事情传播行为的概念,即propagation参数,默认等于PROPAGATION_REQUIRED,表示若手上从未有过工作,就新建一个业务,如果有一个事务,方法块用下是业务。

//#Spring的transactionAttributes的配置
//PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
//PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
//PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
//PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
//PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
//PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
//PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作

十、webx学习(三剑客:listener、filter、servlet)

<!-- 初始化日志系统 -->
<listener>
    <listener-class>com.alibaba.citrus.logconfig.LogConfiguratorListener</listener-class>
</listener>

<!-- 装载/WEB-INF/webx.xml, /WEB-INF/webx-*.xml -->
<listener>
    <listener-class>com.alibaba.citrus.webx.context.WebxContextLoaderListener</listener-class>
</listener>

 

  这里是全部Webx应用之起点,声明了一个listener。顾名思义,listener就是监听者,它竖起耳朵监听了容器的轩然大波,当容器发生局部事情时,它将会见做出预先定义之动作。Webx用LogConfiguratorListener来初始化日志系统。LogConfiguratorListener会根据你时使用所依赖的日志系统(通常配置当maven
project中),来自动选择适当的日志配置文件。假设你的应用依赖了logback的jar包,那么listener就见面寻找/WEB-INF/logback.xml,并因而她来初始化logback;如果你的施用靠了log4j的jar包,那么listener也会充分聪明地摸/WEB-INF/log4j.xml配置文件。假如以上配置文件未设有,listener会使用默认的布局,把日志打印在控制台上。Listener支持对部署文件被的placeholders进行调换。Listener支持以初始化多种日记系统。看WebxContextLoaderListener这个类名:Webx环境加载器监听者。我们可以知晓,这个监听器是负责在开行的时加载Webx环境之。

public class WebxContextLoaderListener extends ContextLoaderListener {
    ...
}

public class ContextLoaderListener implements ServletContextListener {
    ...
}
public interface ServletContextListener extends EventListener {

    public void contextInitialized ( ServletContextEvent sce );

    public void contextDestroyed ( ServletContextEvent sce );
}

足见,WebxContextLoaderListener继承了ContextLoaderListener,而ContextLoaderListener实现了EventListener接口。接口是干嘛用之吗?容器初始化完成后举行的作业;容器销毁后召开的业务;这便是EventListener接口。只要你的listener实现了此接口,容器初始化和销毁的下就要调用这点儿只接口方法。所以,这个进程总结起来便,容器根据web.xml里之马上段描述实例化WebxContextLoaderListener,然后于初始化完成的时刻调用该实例的contextInitialized方法,从而实现了一致种植通知机制。下面是WebxContextLoaderListener的满贯源代码。

public class WebxContextLoaderListener extends ContextLoaderListener {
    @Override
    protected final ContextLoader createContextLoader() {
        return new WebxComponentsLoader() {

            @Override
            protected Class<? extends WebxComponentsContext> getDefaultContextClass() {
                Class<? extends WebxComponentsContext> defaultContextClass = WebxContextLoaderListener.this
                        .getDefaultContextClass();

                if (defaultContextClass == null) {
                    defaultContextClass = super.getDefaultContextClass();
                }

                return defaultContextClass;
            }
        };
    }

    protected Class<? extends WebxComponentsContext> getDefaultContextClass() {
        return null;
    }
}

  createContextLoader返回的凡一个ContextLoader类的实例;方法里new出来一个WebxComponentsLoader的实例作为返回值,因此,这个返回值实际上是WebxComponentsLoader类的实例;方法把此实例new出来的早晚,顺便覆盖了瞬间WebxComponentsLoader类的getDefaultContextClass方法,因此,返回的实例实际上是一个WebxComponentsLoader类的匿名子类的实例,且这个子类覆盖了getDefaultContextClass方法。

  实现了EventListener接口,就可以当容器初始化完成的时节获得关照,因此,我们看WebxContextLoaderListener这个近乎对contextInitialized方法的兑现。容易察觉,它经过持续ContextLoaderListener方法实现了之法,因此是方法会在容器初始化的时光给容器调用:

 

public class ContextLoaderListener implements ServletContextListener {

    private ContextLoader contextLoader;

    /**
     * Initialize the root web application context.
     */
    public void contextInitialized(ServletContextEvent event) {
        this.contextLoader = createContextLoader();
        this.contextLoader.initWebApplicationContext(event.getServletContext());
    }
    ...
}

 

  这个办法做了一定量宗工作:用createContextLoader方法新建一个contextLoader成员并且调用其initWebApplicationContext方法。显然,ContextLoader就是条件加载器,主要作用就是是加载并启动下文会讲到之WebApplicationContext。除此之外,由于WebxContextLoaderListener覆盖了createContextLoader方法,因此当我们的启动过程遭到,实际上调用的是顶尖个代码中的createContextLoader方法。所以,这个新建的长河返回的是WebxComponentsLoader类的匿名子类的实例,从而,调用的initWebApplicationContext方法呢是WebxComponentsLoader类的initWebApplicationContext方法。

 

<filter>
    <filter-name>mdc</filter-name>
    <filter-class>com.alibaba.citrus.webx.servlet.SetLoggingContextFilter</filter-class>
</filter>

<filter>
    <filter-name>webx</filter-name>
    <filter-class>com.alibaba.citrus.webx.servlet.WebxFrameworkFilter</filter-class>
    <init-param>
        <param-name>excludes</param-name>
        <param-value><!-- 需要被“排除”的URL路径,以逗号分隔,前缀!表示“包含”。例如/static, *.jpg, !/uploads/*.jpg --></param-value>
    </init-param>
    <init-param>
        <param-name>passthru</param-name>
        <param-value><!-- 需要被“略过”的URL路径,以逗号分隔,前缀!表示“不要略过”。例如/myservlet, *.jsp --></param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>mdc</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>webx</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

 

  SettLoggingContextFilter于经是filter的时光,加有异常的日志上下文,比如说请求的url。WebxFrameworkFilter是webx控制器的filter,用来接有的要:可卜的参数:“排除”指定名称的path,以逗号分隔,例如:/static,
.jpg。如果路径为!开始,表示“不脱”特殊目录。例如:.jpg,
!/uploads/*.jpg代表免除有JPG图像文件,但非免除/uploads目录下之JPG图像文件;可选的参数:“略过”指定名称的path,以逗号分隔,例如:/myservlet,
*.jsp。和excludes参数一样,也支撑!前缀,表示“不要略过”特殊目录;匹配有的path。WebxFrameworkFilter处理一个WEB请求的长河如下:

图片 3

  如图所示,WebxFrameworkFilter接到请求后,就见面调用WebxRootController。从这里开始,进入Spring的世界,此后所有的靶子:WebxRootController、WebxController、RequestContext、Pipeline等,全部凡是经过SpringExt配置于Spring
Context中之。WebxRootController对象是于root
context被,它吃所有子应用所共享。它会创RequestContext实例 ——
从而增强request、response、session的功效。接下来,WebxController对象会受调用。WebxController对象是出于每个子应用独享的,子应用app1和app2可以生出差之WebxController实现。默认的贯彻,会调用pipeline。Pipeline也是由于各子应用自己来安排的。假如pipeline碰到无法处理的伸手,如静态页面、图片等,pipeline应当实行<exit/>
valve强制退出。然后WebxRootController就会见“放弃控制”,这意味request将受归还给/WEB-INF/web.xml中定义之servlet、filter或者返还给servlet
engine本身来拍卖。

  MVC理解,MVC
是同样种植使 MVC(Model View Controller 模型-视图-控制器)设计创建 Web
应用程序的模式:Model(模型)是应用程序中用于拍卖应用程序数据逻辑的有的。通常模型对象承担在数据库被存取数据。View(视图)是应用程序中处理数据展示的片。通常视图是依据模型数据创建的。Controller(控制器)是应用程序中拍卖用户交互的一部分。通常控制器负责从视图读取数据,控制用户输入,并于范发送数据。MVC
分层有助于管理复杂的应用程序,可以当一个时光内特意关注一个者。例如,您得以无借助于工作逻辑的景下专注让视图设计。同时也给应用程序的测试更加爱。MVC
分层同时为简化了分组开发。不同之开发人员可又出视图、控制器逻辑和事务逻辑。

十一、webx3的启动过程及webx3的平等潮呼吁流程:地址

十二、HSF学习

  HSF作为阿里底底蕴当中件组件,旨在为集团以提供一个分布式的服务框架,HSF
从分布式应用层面与联合之发布/调用方式层面为大家提供支撑,从而得以十分轻之支付分布式的下和提供和运用公用功能模块,而不要考虑分布式领域中的各种细节技术,例如进程通讯、性能损耗、调用的透明化、同步/异步调用方式的兑现等等问题。HSF是一个
RPC 框架,远程调用对端的地点便是由于 ConfigServer
来推送的,这样用户就需要配备好的服务端或者消费端,不需对团结的地点进行管制。我们调用远程服务之主意来过多,比如发一个http请求过去,返回一个json数据,直接用jasonRpc的情商,或者webservice等。但是还出一个合办之问题,对开发人员不自己,它需要侵入业务流程,不得不被上层应用在代码中呢rpc调用写有错综复杂丑陋的代码。而HSF是基于接口编程的。如果自己而调用某个服务,那我一旦用到者服务的接口,直接调用就足以了。只要将接口注册改成一个长途调用的接口,对利用来说即使非需举行其他工作。

  注册中心configServer,我怀念调用一个劳动,首先自己需要明白之服务的机的地方,端口号是稍稍。在hsf中是消息就是保存于注册中心及呢便是ConfigServer。我晓得的她的打算就是管制整个分布式集群里富有的劳务对应服务提供者ip的附和关系,方便扩容缩容,服务地方ip的扭转。通过挂号中心远程调用服务的过程可为此生图来叙述。

图片 4

  ConfigServer是独推送模型,当服务初始化消费者去订阅的时光便会见推送地址,每当服务提供者发生变更(扩容,缩容)时,也会如消费者进行推送。那推送模型会发生啊补,会设有什么问题?TODO。

图片 5

HSF架构图:

  Proxy层:主要处理部分HSF和采用交互的局部逻辑,比如说做接口的代办,比如说去执行工作的法门。

  Remoting层:主要处理部分网络层中之应用层数据,和人情的应用层的多寡有分别的凡,他是一律栽网络协议,但他是处在TCP之上的,也便是网络协议中危成的应用层。其实根本是拍卖RPC商讨。

十三、

 

网站地图xml地图