Spring MVC源码探究

作为一名合格的java程序员,要多深入学习一些框架,理解框架的设计的方法,背后的原理,spring mvc框架中使用了很多设计模式,比如策略模式,Spring MVC中大量使用了策略模式,像HandlerMapping接口,HandlerAdapter接口,ViewResolver接口都使用了策略模式,在执行handler和Interceptor拦截器的时候使用了责任链模式,在执行handler的时候会用到适配器模式等等,可以说沉淀了很多前辈的精华,想成为架构师的话,学习源码必不可少,下面就围绕着Spring MVC 的前端控制器DispatcherServlet一步一步的来学习Spring MVC的源码。 1 web.xml中DispatcherServlet的配置web.xml中的Spring MVC的前端控制器DispatcherServlet的配置,所有后端Controller的请求都由这个DispatcherServlet分发。 123456789101112<servlet> <servlet-name>MySpringServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/spring-mvc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>MySpringServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>

spring框架

Java集合中的Fail-fast和Fail-Safe机制

1.何为Fail-fast和Fail-Safe机制?java.util包里的Iterator 抛出 ConcurrentModificationException异常, 在集合迭代的时候被集合的add方法或者 remove方法调用。fail-fast 指java的集合的一种错误机制,当多个线程对集合修改操作的时候就可能抛出ConcurrentModificationException异常。 java.util.concurrent包里的Iterator 通过迭代一个集合的snapshot 允许并发修改集合,但是在迭代器创建之后可能不反映Collection更新。fail-safe机制意味着多个线程在操作同一个集合的时候,不会出现ConcurrentModificationException异常,但是需要复制集合获得集合的快照,所以性能上开销会比非同步的集合开销要大。 多线程环境下用java.util.concurrent包里的集合替代 java.util包里的集合,比如 CopyOnWriteList=>ArrayList,ConcurrentHashMap=>HashMap etc. 2.JDK中的源码分析下面代码是JDK1.7源码中ArrayList中的ListIterator,当Iterator创建时,当前的计数器modCount 赋值给Iterator对象,注意到modCount是一个 transient类型的成员变量,transient说明了计数器将不被序列化。 protected transient int modCount = 0; modCount用来记录List修改的次数的计数器,每修改一次(添加/删除等操作),将modCount+1,例如 add()方法: 1234567public void add(int index, E element) { rangeCheckForAdd(index); checkForComodification(); l.add(index+offset, element); this.modCount = l.modCount; size++; }

java

学习Java的NIO

重要的概念 什么是NIO?NIO是从java 1.4 开始引入的一个新的 IO API。 Channel、Buffer、Selector是NIO的核心部分。 IO通过字节流和字符流操作数据,NIO基于通道(Channel)和缓冲区(Buffer)数据 Channel&BufferChannel数据总是由通道到缓冲区(Read),或者由缓冲区到通道(write) 其中Channel的几个实现 FileChannel DatagramChannel SocketChannel ServerSocketChannel 分别对应文件IO/UDP/TCP网络IO. 下面是一个简单的例子实现,从本地文件系统读取数据到Buffer中。

java

Scala中的特质

特质的构造顺序 1. 超类的构造器 2. 特质由左至右构造 3. 每个特质中,父特质先被构造 4. 多个特质公用一个父特质,而那个特质已经被构造,则不会被再次构造 5. 所有特质构造完毕,子类被构造 eg: 其中 FileLogger和ShortLogger都继承Logger特质 1calss SavingsAccount extends Account with FileLogger with ShortLogger 构造顺序 1.Account(超类) 2.Logger(第一个特质的父特质) 3.FileLogger(第一个特质) 4.ShortLogger(第一个特质) 5.SavingAccount(类)

scala

Java中的null引用

空指针也许是java中最常见的异常,到处都埋藏着NullpointerException,最近就遇到一个NullPointException,如下: 1int lastMonthTotalScore = integralOperationReadMapper.getSumByIntegralIdAndDate(integralId, lastMonthDate); 一个很常见的情况,mybatis查询的一个列的和,此时Debug时 integralId、lastMonthDate 都不为空,自动注入的 integralOperationReadMapper也不为空但是Console却实实在在的打出了这一行有一个NullPointerException,此时没有注意到Wrapper类自动转换基本数据类型的情形。 getSumByIntegralIdAndDate 方法返回的是NULL,自动拆箱的时候的要将一个NULL转换为基本数据类型就出错了…o(╯□╰)o 现在总结几个NULL的经验。 1.不用null来返回方法的返回值 不要用null来舒适化变量,方法不要返回null、这样会造成null的传播,在每一个调用的地方都需要检查null 例如: 12345public String doSomething(int id){ String name = findName(id); ... return name;} 这样如果findName如果返回为null,那么null就由findname游走到了doSomething。比如在findname中,如果没有找到对应的Id的姓名,就应该表明是没找到,而不是出错了。 善于运用Java的异常。 1234567public String findName() throws NotFoundException { if (...) { return ...; } else { throw new NotFoundException(); } }

java

Scala中的模式匹配

模式匹配scala有一套内建的模式匹配机制,这种机制允许在任何类型的数据上与第一个匹配策略匹配。模式匹配可以应用在很多场合,switch语句,类型检查以及提取对象中的的复杂表达式。 下面是一个小例子,说明如何与一个整型值匹配: 12345678object MatchTest1 extends App { def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" case _ => "many" } println(matchTest(3))}

scala

使用Scala实现快速排序

首先是一个用Scala写的简单的快速排序的栗子(非函数式): 123456789101112131415161718192021def sort(xs: Array[Int]) { def swap(i: Int, j: Int) { val t = xs(i); xs(i) = xs(j); xs(j) = t } def sort1(l: Int, r: Int) { val pivot = xs((l + r) / 2) var i = l; var j = r while (i <= j) { while (xs(i) < pivot) i += 1 while (xs(j) > pivot) j -= 1 if (i <= j) { swap(i, j) i += 1 j -= 1 } } if (l < j) sort1(l, j) if (j < r) sort1(i, r) } sort1(0, xs.length - 1) }

scala

函数式编程语言Scala的学习(Hello Scala)

Scala吸收了收并继承了多种语言中的优秀特性,另一方面也没有抛弃Java这个强大的平台,它可以运行在 Java 虚拟机之上,能够轻松地与Java互联互通。与Java不同的是,Scala既支持面向对象的特性,又支持函数式编程,被称为是Java的替代语言,是更好的Java,下面开始学习这一强大的语言。 Scala和Java比较在Scala中 所有类型都是对象 函数是对象 支持Domain specific language (DSL)领域特定语言 特质(Trait) 闭包(Closure),嵌套函数 Erlang支持的并发设计 类型推导 基础语法表达式scala> 1 + 1 res0: Int = 2 res0是解释器自动创建的变量名称,指代表达式计算的结果,是Int类型的,值为2。在scala几乎一切都是表达式。 变量和值可以将表达式赋给一个或者不变量(val)–值或者变量(var) scala> val two = 1 + 1 two: Int = 2 如果需要以后修改这个名称和结果的绑定,需要使用var(变量),大部分的情况下用val的情况居多。 scala> var name = "zhaohongxuan" name: java.lang.String = zhaohongxuan scala> name = "zhaoxiaoxuan" name: java.lang.String = zhaoxiaoxuan

scala

使用Spring boot 创建RestFul服务

准备工作1.JDK82.Maven 3.0+ 程序要实现的简单功能当用户访问 http://localhost:8080/greeting 返回一个默认的Json字符串 {"id":1,"content":"Hello, World!"} 当用户访问 http://localhost:8080/greeting?name=User 返回 name后面的参数在后台组成的字符串 {"id":1,"content":"Hello, User!"} 创建Maven项目创建一个普通的maven项目,添加maven依赖如下:

spring框架

Executor任务执行框架的应用

最近一段时间没有写东西了,看大名鼎鼎的Brian Goetz写的Java Concurrency in Practice时候,看到任务执行框架Executor Framework的时候,觉得纸上得来终觉浅,索性写点东西加深一下印象。 在JDK1.5中,Java平台中增加了一个并发包java.util.concurrent,这个包中包含了Executor Framework,而且还包含了很多并发包,比如并发HashMapConcurrentHashMap、阻塞队列BlockQueue、栅栏的实现CyclicBarrier、信号量Semaphore、异步任务FutureTask等等。在处理多线程任务的时候,使用Executor和task要优于使用线程,这也不是我说的,是Effect Java的作者 Joshua Bloach说的,下面来阐述一下为什么。 并发任务执行当要执行一个并发任务的时候,通常有两种方式,一种是串行的处理方式,一种是并行的处理,显然,串行的方式只能一次处理一个任务,当程序在执行当前的任务的时候,就说明接下来到来的任务请求都要等待当前的任务执行完毕才能获得CPU去执行任务,这种方式虽然不会犯错,但是效率太低。那么,如果每一个任务到来都分配一个新的任务呢,这种方式貌似很好,但是: 如果任务请求量非常大的时候会出现一定的问题,因为它没有限制可以创建的线程的数量. 线程生命周期的开销很高 线程的创建和销毁不是没有代价的,根据平台的不同,开销不同,但是不要忘记,线程的创建是需要时间的。 活跃的线程会消耗系统资源 活跃的线程很消耗系统资源,尤其是内存,如果可运行的线程数量多于处理器核心数,那么多余的线程将闲置,但是闲置的线程仍然是消耗系统资源的,尤其 是内存,给GC回收垃圾带来压力,而且线程间在进行竞争的时候也会消耗大量的资源 平台可创建的线程数量是有限的 也就是说,如果创建的线程超出了平台的限制那么,JVM就可能抛出OutofMemoryError的异常

java
1678910

本站由 Hank Zhao 使用 Stellar 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
本站总访问量