Java基础

命令行运行java

jar包都放在lib文件夹里

java -Djava.ext.dirs=lib Main

ubuntu 安装jdk

http://www.cnblogs.com/a2211009/p/4265225.html

jre是提供java运行环境而不是开发环境
OpenJDK 和 Sun JDK 的关系

Map的较简单构建方式:

new HashMap(){{
            put("saleState",saleState);
            put("serveType",serveType);
        }}

Java字段反射+POI示例:
http://blog.csdn.net/panpan96/article/details/76566475

Java没有范型数组

new ArrayList<List>(){{
add(masterSocketDeviceIds);
add(dimmingLightDeviceIds);
}};

枚举

ordinal()是返回的值是索引,value()返回的是给枚举变量赋予的值。

public enum EnumDeviceType {
    Unknow(0),
    MasterSocket(1),
    SlaveSocket(2),
    DoorbellController(42),
    PowerControl(43);

    private int value = 0;

    private EnumDeviceType(int value) {
        this.value = value;
    }

    public int value() {
        return value;
    }
}

JVM

JVM

JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

Java语言的一个非常重要的特点就是与平台的无关性,使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码,Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。

http://www.mamicode.com/info-detail-1028149.html

HotSpot VM

HotSpot VM是绝对的主流的JVM。大家用它的时候很可能就没想过还有别的选择,或者是为了迁就依赖了Oracle/Sun JDK某些具体实现的烂代码而选择用HotSpot VM省点心。Oracle / Sun JDK、OpenJDK的各种变种(例如IcedTea、Zulu),用的都是相同核心的HotSpot VM。从Java SE 7开始,HotSpot VM就是Java规范的“参考实现”(RI,Reference Implementation)。把它叫做“标准JVM”完全不为过。当大家说起“Java性能如何如何”、“Java有多少种GC”、“JVM如何调优”云云,经常默认说的就是特指HotSpot VM。可见其“主流性”。JDK8的HotSpot VM已经是以前的HotSpot VM与JRockit VM的合并版,也就是传说中的“HotRockit”,只是产品里名字还是叫HotSpot VM。不过要留意的是,这里我说的HotSpot VM特指“正常配置”版,而不包括“Zero / Shark”版。Wikipedia那个页面上把后者称为“Zero Port”。用这个版本的人应该相当少,很多时候它的release版都build不成功…

JVM调优-分代垃圾回收

分代垃圾回收采用分而治之的思想,进行代的划分,把不同生命周期的对象放在不同代上,不同代上采用最适合它的垃圾回收方式进行回收。

虚拟机中的共划分为三个代:年轻代(Young Generation)、年老代(Old Generation)和持久代
(Permanent Generation)。

年轻代
所有新生成的对象首先都是放在年轻代的。年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象。

老年代
在年轻代中经历了N次垃圾回收后仍然存活的对象,就会被放到年老代中。因此,可以认为年老代中存放的都是一些生命周期较长的对象。

持久代
持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大。

什么情况下触发垃圾回收?

由于对象进行了分代处理,因此垃圾回收区域、时间也不一样。GC有两种类型:Scavenge GC和Full GC。

Scavenge GC(搜寻)
一般情况下,当新对象生成,并且在Eden申请空间失败时,就会触发Scavenge GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区。然后整理Survivor的两个区。这种方式的GC是对年轻代的Eden区进行,不会影响到年老代。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的GC会频繁进行。因而,一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

Full GC
对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个对进行回收,所以比ScavengeGC要慢,因此应该尽可能减少Full GC的次数。在对JVM调优的过程中,很大一部分工作就是对于FullGC的调节。有如下原因可能导致Full GC:
· 年老代(Tenured)被写满
· 持久代(Perm)被写满
· System.gc()被显示调用

从JDK1.2版本开始,把对象的引用分为四种级别,从而使程序能更加灵活的控制对象的生命周期。这四种级别由高到低依次为:强引用、软引用、弱引用和虚引用。

特别注意,在程序设计中一般很少使用弱引用与虚引用,使用软引用的情况较多,这是因为软引用可以加速JVM对垃圾内存的回收速度,可以维护系统的运行安全,防止内存溢出(OutOfMemory)等问题的产生。

https://my.oschina.net/ydsakyclguozi/blog/404389

Spring-AOP

定义装备

定义切点

Spring中表示方式切点常用的有两种方式:1.使用正则表达式 2.使用AspectJ表达式
使用org.springframework.aop.support.JdkRegexpMethodPointcut来定义正则表达式切点

<bean id="sleepPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
 <property name="pattern" value=".*sleep"/>
</bean>

上面示例中pattern属性指定了正则表达式,它匹配所有的sleep方法

定义顾问

把通知和切点结合起来:
org.springframework.aop.support.DefaultPointcutAdvisor

<bean id="sleepHelperAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
 <property name="advice" ref="sleepHelper"/>
 <property name="pointcut" ref="sleepPointcut"/>
</bean>

定义代理对象

<bean id="humanProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
     <property name="target" ref="human"/>
     <property name="interceptorNames" value="sleepHelperAdvisor" />
     <property name="proxyInterfaces" value="test.spring.aop.bean.Sleepable" />
</bean>

Spring还提供了一种自动代理的功能,不用显示定义代理对象,能让通知者和业务对象自动匹配,如下:

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

http://blog.csdn.net/udbnny/article/details/5870076
http://www.jb51.net/article/83173.htm

AOP概念

AOP是Aspect Oriented Programming的缩写,意思是面向切面(方面)编程。主要的功能有日志记录,性能统计,安全控制,事务处理,异常处理等,主要意图是将功能代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。AOP是其实是通过动态代理模式来实现业务逻辑的插入,使开发者在开发时不用关注其他与业务无关的点,通过代理的方式做到了插拔式操作。

AOP,OOP区别概念

  • AOP是OOP的补充
  • OOP编程将程序分解成各个层次的对象,AOP将程序运行过程分解成各个切面。
  • AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,
  • OOP是静态的抽象,AOP是动态的抽象,
  • AOP是对应用执行过程中的步骤进行抽象,从而获得步骤之间的逻辑划分。

AOP框架具有的两个特征:
1.各个步骤之间的良好隔离性
2.源代码无关性

IOC概念

IoC,(Inverse of Control)控制反转,其包含两个内容:其一是控制,其二是反转。在程序中,被调用类的选择控制权从调用它的类中移除,转交给第三方裁决。这个第三方比如Spring容器。IoC另解,依赖注入(Dependency Injection),调用类对被调用类的依赖关系由第三方注入。
IoC其实是遵循了软件设计理念的依赖倒转原则,面向对象的设计就是为了实现软件的更好的复用行和扩展性,我们就必须降低我们每个pojo的依赖关系,也就是解耦,耦合度低了,才能更好的重用和扩展。
IoC中用到了工厂模式

WebService

JAX-WS全称是JavaTM API forXML-Based WebServices
JAX-RS全称是JavaTM APIforRESTful Web Services
JAX-WS是针对WebService,JAX-RS是针对RESTful HTTP Service
这是两种风格的SOA架构风格:
JAX-WS以动词为中心,指定的是每次执行函数,大力支持的厂商如BEA,IBM,MS基本都是开发工具厂商
JAX-RS以名词为中心,每次执行的时候指的是资源,大力支持的厂商如Google,Yahoo,亚马孙等都是服务运营厂商

soap rest 区别
http://www.cnblogs.com/zhangchenglzhao/p/3728455.html

以前旧的基于方法的Web Service都是属于JAX-WS,现在较新的RESTful的Web Service则是属于JAX-RS。其中Jersey是SUN的JAX-RS的参考实现,RESTeasy则是Jboss的JAX-RS的实现。RESTful的Web Service简单来说就是将所有东西看作资源,每个资源都有一个URI,对资源的CRUD操作借助于HTTP协议的POST、GET、PUT、DELETE来实现。效率比旧的基于方法的Web Service要高。

开源WebService框架
CXF、Axis,SpringRMI

TCP服务器

可选的TCP服务器有Mina、Netty、Twisted等,它们都是异步、事件驱动(asynchronous、event-driven)的网络编程框架。
其中MINA和Netty是基于Java语言的,Twisted是Python语言的。语言不是重点,重点的是理念。

  • 传统的BIO(Blocking IO/阻塞IO)进行网络编程时,进行网络IO读写时都会阻塞当前线程,使用BIO实现一个TCP服务器,需要对每个客户端连接开启一个线程,很多线程可能会阻塞住等待读写数据,系统资源消耗大。
  • NIO(Non-Blocking IO/非阻塞IO)或AIO(Asynchronous IO/异步IO)通过IO多路复用技术实现,不需要为每个连接创建一个线程,其底层实现使用了操作系统的一些特性如select、pool、epoll、iocp等。

Mina、Netty、Twisted一起学(一):实现简单的TCP服务器
Netty 4.x 用户指南
Netty in Action 学习
一起学Netty
netty(一) java NIO

同步阻塞I/O

Java的两个IO方法 read和write都是同步阻塞的。
阻塞指的是read和write都会阻塞线程直到读取或发送完成或异常。
同步指的是发送方和接收方是同步的,缓慢的发送和网络传输会使接收长时间阻塞,缓慢的接收和网络传输和狭小的TCP缓冲区也会使发送长时间阻塞,所以发送和接收的速度互相影响。
输入流和输出流的读和写操作都是同步阻塞的,阻塞的时间取决于对方I/O线程的处理速度和网络I/O的传输速度。

Java NIO

JDK1.4引入了新的输入/输出(NIO)库。相比jdk1.3,NIO弥补了原来同步阻塞I/O的不足,提供了高速的、面向块的I/O。
一些NIO新增的类库和概念:
1.缓冲区Buffer
在面向流的I/O中,可以将数据直接写入或读到Stream对象中。
在NIO库中,数据读写都是要经过缓冲区。缓冲区实质上是一个数组,并且一个缓冲区不仅仅是一个数组,它还提供了对数据的结构化访问以及维护读写位置(limit)等信息。
最常用的缓冲区是ByteBuffer,一个ByteBuffer提供了一组功能用于操作byte数组。包括ByteBuffer,每一种java基本类型(除了Boolean类型)都对应一种缓冲区:
ByteBuffer:字节缓冲区
CharBuffer:字符缓冲区
ShortBuffer:短整型缓冲区
IntBuffer:整形缓冲区
LongBuffer:长整型缓冲区
FloadBuffer:浮点型缓冲区
DoubleBuffer:双精度浮点型缓冲区
2.通道Channel
通道与流的不同之处在于通道是双向的,可以用于读、写或者二者同时进行,流只是在一个方向上移动(一个流必须是InputStream或者OutputStream的子类)。
因为Channnel是双全工的,所以它可以比流更好地映射底层操作系统的API。在UNIX网络编程模型中,底层操作系统的通道都是双全工的,同时支持读写操作。
实际上Channel可以分为两大类:用于网络读写的SelectbleChannel和用于文件操作的FileChannel。
与Socket类和ServerSocket类相对应,NIO提供了SocketChannel和ServerSocketChannel两种不同的套接字通道实现,它们都是SelectableChannel的子类,都支持阻塞和非阻塞两种模式。
3.多路复用器Selector
多路复用器提供选择已经就绪的任务的能力。Selector会不断地轮询注册在其上的Channel,如果某个Channel上面发生读写事件,这个Channel就处于了就绪状态,处于了就绪状态的Channel会被Selector轮询出来,然后通过SelectionKey可以读取就绪Channel集合,进行后续的I/O操作。
JDK在Linux等主流操作系统上通过epoll实现,所以它并没有最大连接句柄1024/2048的限制。这意味着只需要一个线程负责Selector的轮询,就可以接入成千上万的客户端。
Reactor反应器模式:使用单线程模拟多线程,提高资源的利用率和程序的效率,增加系统吞吐量。
Selector类似一个观察者,我们把需要探知的socketchannel告诉Selector,当有事件发生时,Selector会通知我们并传回一组SelectionKey,我们读取这些Key,会获得注册过的socketchannel,然后从这个Channel中读取数据。即主程序不用主动阻塞的等待数据,而是被通知有数据就绪。
4.AIO
JDK1.7升级了NIO类库,升级后的NIO类库被成为NIO2.0,正式提供了异步文件I/O操作,同时提供了与UNIX网络编程事件驱动I/O对应的AIO。NIO2.0引入了新的异步通道的概念,并提供了异步文件通道和异步套接字通道的实现。异步通道提供以下两种方式获取操作结果。
(1)通过java.util.concurrent.Future类来表示异步操作的结果;
(2)在异步操作的时候传入一个java.nio.channels.CompletionHandler接口的实现类作为操作完成的回调。
NIO2.0的异步套接字通道是真正的异步非阻塞I/O,对应了UNIX网络编程中的事件驱动I/O(AIO),它不需要通过多路复用器(selector)对注册的通道进行轮询操作即可实现异步读写,从而简化了NIO的编程模型。

Base 128 Varints

Google Protobuf3

Google Protobuf 官方文档之Language Guide (proto3)
http://blog.163.com/lnsjc321@126/blog/static/5348428720154325730234/
https://developers.google.com/protocol-buffers/docs/proto3

Java多线程

Runnable

Runnable不是线程,它只是一个接口定义了一个方法,Thread启动才是一个线程。

Thread

thread.join()方法
在主线程中调用子线程的join方法,目的是使主线程阻塞,直到子线程执行完毕才返回到主线程中。
简单理解,在主线程中调用t.join(),也就是在主线程中加入了t线程的代码,必须让t线程执行完毕之后,主线程(调用方)才能正常执行。

线程同步

线程同步一般是要解决在“单对象多线程”的情况下,控制共享变量的访问,或是控制执行步骤顺序。
控制共享变量的策略:

  • 将“单对象多线程”修改成“多对象多线程”;
  • 将“全局变量”降级为“局部变量”;
  • 使用ThreadLocal机制,它用于解决线程间共享变量,使用ThreadLocal声明的变量,即使在线程中属于全局变量,针对每个线程来讲,这个变量也是独立的。
  • 用final域,有锁保护的域和volatile域可以避免非同步的问题。

使用特殊域变量(volatile)实现线程同步
a.volatile关键字为域变量的访问提供了一种免锁机制,
b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新,
c.因此每次使用该域就要重新计算,而不是使用寄存器中的值
d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量

控制执行步骤
执行步骤可以使用synchronized关键字来解决
java的每个对象都有一个内置锁,当用synchronized关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则调用者就停在阻塞状态。
synchronized的原理和数据库中事务锁的原理类似。在使用过程中应该尽量缩减synchronized覆盖的范围,原因是被它覆盖的范围是串行的,效率低,并且容易产生死锁。
通常没有必要同步整个方法,使用synchronized代码块同步关键代码即可。

JDK中的concurrent工具包

JavaSE5.0中新增了一个java.util.concurrent包来支持同步。
concurrent工具包中也提供了线程池,分为3类:ScheduledThreadPool、FixedThreadPool和CachedThreadPool。
有些情况下需要使用线程的返回值,可以使用JDK中的Callable和CompletionService,前者返回单个线程的结果,后者返回一组线程的结果。
在concurrent工具包中,我们可以使用BlockingQueue来实现生产者-消费者模型。
使用信号量来控制线程:
JDK提供了Semaphore来实现“信号量”的功能,它提供了两个方法分别用于获取和释放信号量:acquire和release.
可以用synchronized关键字来控制单个线程中的执行步骤,要对线程池中的所有线程的执行步骤进行控制的,有两种方式,一种是使用CyclicBarrier,一种是使用CountDownLatch。
CyclicBarrier使用了类似于Object.wait的机制,它的构造函数中需要接收一个整型数字,用来说明它需要控制的线程数目,当在线程的run方法中调用它的await方法时,它会保证所有的线程都执行到这一步,才会继续执行后面的步骤。
CountDownLatch则是采取类似”倒计时计数器”的机制来控制线程池中的线程,它有CountDown和Await两个方法。
使用重入锁实现线程同步
ReentrantLock类是可重入、互斥、实现了Lock接口的锁,它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力。
关于Lock对象和synchronized关键字的选择:
如果synchronized关键字能满足用户的需求,就用synchronized,因为它能简化代码
如果需要更高级的功能,就用ReentrantLock类,此时要注意及时释放锁,否则会出现死锁,通常在finally代码释放锁

局部变量实现线程同步
如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。
ThreadLocal与同步机制
ThreadLocal与同步机制都是为了解决多线程中相同变量的访问冲突问题。
ThreadLocal采用以”空间换时间”的方法,同步机制采用以”时间换空间”的方式

Future

java中Future是一个未来对象,里面保存线程处理结果,它像一个提货凭证,可以随时去提取结果。
在两种情况下离开Future较难处理:

  • 一种情况是拆分订单,比如应用收到一个批量订单,此时如果要求最快的处理订单,那么需要并发处理,并发的结果如何收集的问题如果自己编程非常繁琐,此时可以使用CompletionService解决这个问题。CompletionService将Future收集到一个队列里,可以按结果处理完成的先后顺序进队。
  • 另一种情况是如果需要并发查询一些东西(比如爬虫),并发查询只要有一个结果返回就认为查询到了,并且结束查询,这时也需要用CompletionService和Future来解决。

Java特性

Java8

Java 8发行版是自Java 5(发行于2004)以来最具革命性的版本。Java 8 为Java语言、编译器、类库、开发工具与JVM(Java虚拟机)带来了大量新特性。
Java SE 8中的一些特性:

  • 函数式接口(functional interface)与lambda表达式
  • 方法和构造方法引用
  • 接口的默认方法

函数式接口(functional interface)与lambda表达式

简单来说,函数式接口是只包含一个抽象方法的接口,即像使用函数似的使用这个接口。比如Java标准库中的java.lang.Runnable和java.util.Comparator都是典型的函数式接口。函数式接口还可以使用lambda表达式来创建实现对象。
使用lambda表达式时,只需要提供形参和方法体。由于函数式接口只有一个抽象方法,所以通过lambda表达式声明的方法体就肯定是这个唯一的抽象方法的实现,而且形参的类型可以根据方法的类型声明进行自动推断。
比较下面两个方法:

public void runThread() {
    new Thread(new Runnable() {
        public void run() {
            System.out.println("Run!");
        }
    }).start();
}
public void runThreadUseLambda() {
    new Thread(() -> {
        System.out.println("Run!");
    }).start();
}

Java SE 8增加了java.util.function包,里面都是可以在开发中使用的函数式接口。开发人员也可以创建新的函数式接口。最好在接口上使用注解@FunctionalInterface进行声明,以免团队的其他人员错误地往接口中添加新的方法。

方法和构造方法引用(Method References)

方法引用是另外一种实现函数式接口的方法,在某些情况下,方法引用可以进一步简化代码。
Java 8中的方法也是一种对象,可以By名字来引用。不过方法引用的唯一用途是支持Lambda的简写,使用方法名称来表示Lambda。
方法引用可以在不调用某个方法的情况下引用一个方法。
构造方法引用可以在不创建对象的情况下引用一个构造方法。

接口的默认方法

接口的默认方法即在接口中新添加的方法使用default关键词来修饰,并可以有自己的方法体。
接口的默认方法的主要目标之一是解决接口的演化问题。
接口的默认方法的另外一个作用是实现行为的多继承。
通过默认方法,可以创建出类似的帮助接口,即接口中包含的都是通过默认方法实现的帮助方法。
Java 8 接口也可以有静态方法,从职责定位来讲,接口静态方法就是个工具方法。

接口与抽象类

Java之父曾说,若再给他一次设计Java的机会,Java里就不会有抽象类。
总的来说抽象类和接口越来越接近了,是接口向抽象类靠近,剥夺抽象类的生存空间。

  • 抽象类能够定义非static final 的属性(field) ,而接口不能。接口的属性都是static final的。
  • 抽象类能够定义非public方法,而接口不能。接口的方法都是public的。
  • 接口可以多继承(实现),而抽象类不能。抽象类只能单继承。

常量接口(Constant Interface)

常量接口是只包括常量定义的接口,Java中一直存在“常量接口(Constant Interface)”的用法。通过实现这样的接口,就可以省去常量前的挂靠单位而直接引用这些常量。

静态成员导入Static Import

J2SE 1.5里引入了“Static Import”机制,借助这一机制,可以用略掉所在的类或接口名的方式,来使用静态成员。
在Java程序中,是不允许定义独立的函数和常量(当然,准确的说,只是被final修饰、只能赋值一次的变量)的。即使从它们本身的功能来看,完全不需要依附于什么东西,也要找个类或接口作为挂靠单位才行(在类里可以挂靠各种成员,而接口里则只能挂靠常量)。
挂靠的方法,是把它们加上static修饰符,定义为这个类或接口的静态成员。这方面的典型例子是java.lang.Math类——包含了大量的sin、cos这样的“函数”和PI、E这样的“常量”。
传统上,在访问这些挂靠了的函数、变量和常量的时候,需要在前面加上它们挂靠单位的名称。如果只是偶尔访问这些东西一下,这样的写法可以工作得很好;但是如果要频繁访问这些成员的话,这样的写法就显得比较罗嗦了。
静态成员导入没有常量接口的可以从“一个类实现了哪个接口”推断出“这个类需要使用哪些常量”,即“会暴露实现细节”的问题。
使用import static语句,可以导入一个类里的一切被static修饰的东西,包括变量、常量、方法和内类。在J2SE 1.4以后,无论是import语句,还是import static语句,都要求给一个所在包名出来,对于不属于任何包的类和接口,不能用import导入它本身,也不能用import static导入它的静态成员。
import static 包名.类或接口名.*;
注意这种方式只是指出遇到来历不明的成员时,可以到这个类或接口里来查找,并不是把这个类或接口里的所有静态成员全部导入。
静态成员导入只是语法糖的作用,编译时,所有因Static Import的存在而简化了的名字,都会被编译器打回原型。因此在性能方面,Static Import没有任何影响。
但是名字简化却可能造成一些维护方面的问题。去掉静态成员前面的类型名,虽然有助于在频繁调用时显得简洁,但是同时也失去了关于“这个东西在哪里定义”的提示信息,增加了阅读理解的麻烦。所以这一机制在使用不当的时候可能给维护工作带来一定的困扰。

http://www.cnblogs.com/Fndroid/p/6087380.html

搭建SpringMVC开发环境

下载安装jdk,maven,
eclipse(Eclipse Java EE IDE for Web Developers.Version: Mars.2 Release (4.5.2)Build id: 20160218-0600)
http://www.oracle.com/
http://maven.apache.org/

解压maven后,新建环境变量MAVEN_HOME,在PATH里加入maven的bin的路径。
配置完成,可打开命令行,输入mvn -v,测试。
http://dead-knight.iteye.com/blog/1841658

在mac os中配置maven
http://www.jianshu.com/p/191685a33786

下载Spring
http://repo.spring.io/libs-release-local/org/springframework/spring/

在创建maven项目过程中,Select an Archetype时选择maven-archetype-webapp
下一步中Artifact id是工程的名字,Group id是组织的名字,packge可手动置空。
src/main/java是源代码目录
src/main/resources是项目配置目录
src/test/java是测试源代码目录
src/test/resources是测试配置目录
它们都应该出现在java build path中。
由于项目打包、发布时不需要测试代码、测试的配置文件、以及运行时产生的额外文件(target),所以配置web目录也就是Deployment Assembly,不需要src/test及target路径下的内容。

如果报Could not resolve archetype org.apache.maven.archetypes:maven-archetype-webapp
则可能是网络有问题下载地址不能正常访问,等待网络正常。
如果下载一闪而过,而转到这个目录 /Users/admin/.m2/repository/org/apache/maven/archetypes/maven-archetype-webapp,查看其中的内容可能未下载完全,则删除这个目录。
http://blog.csdn.net/afgasdg/article/details/12757433

http://www.iteye.com/topic/973166
http://www.itnose.net/detail/6098368.html

http://www.admin10000.com/document/6436.html
http://blog.csdn.net/clj198606061111/article/details/20492887

jsp文件放到WEB-INFO中可以使其不被直接访问到,WEB-INF是Java的WEB应用的安全目录,客户端无法访问,只有服务端可以访问。如果想在页面中直接访问其中的文件,必须通过web.xml文件对要访问的文件进行相应映射才能访问。

如果报javax.http.servlet找不到,是因国还没有添加Server runtime,在Jararva Build Path/Library中点击add library,选择server runtime…

Spring3.1新特性

Spring2.5之前是通过实现Controller接口或其实现来定义处理器类。
Spring2.5引入注解式处理器支持,通过@Controller 和 @RequestMapping注解定义处理器类,并且提供了一组强大的注解:
需要通过处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter来开启支持@Controller 和 @RequestMapping注解的处理器。
@Controller:用于标识是处理器类;
@RequestMapping:请求到处理器功能方法的映射规则;
@RequestParam:请求参数到处理器功能处理方法的方法参数上的绑定;
@ModelAttribute:请求参数到命令对象的绑定;
@SessionAttributes:用于声明session级别存储的属性,放置在处理器类上,通常列出模型属性(如@ModelAttribute)对应的名称,则这些属性会透明的保存到session中;
@InitBinder:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;
Spring3.0引入RESTful架构风格支持(通过@PathVariable注解和一些其他特性支持),并且又引入了更多的注解支持:
@CookieValue:cookie数据到处理器功能处理方法的方法参数上的绑定;
@RequestHeader:请求头(header)数据到处理器功能处理方法的方法参数上的绑定;
@RequestBody:请求的body体的绑定(通过HttpMessageConverter进行类型转换);
@ResponseBody:处理器功能处理方法的返回值作为响应体(通过HttpMessageConverter进行类型转换);
@ResponseStatus:定义处理器功能处理方法/异常处理器返回的状态码和原因;
@ExceptionHandler:注解式声明异常处理器;
@PathVariable:请求URI中的模板变量部分到处理器功能处理方法的方法参数上的绑定,从而支持RESTful架构风格的URI;
还有比如:
JSR-303验证框架的无缝支持(通过@Valid注解定义验证元数据);
使用Spring 3开始的ConversionService进行类型转换(PropertyEditor依然有效),支持使用@NumberFormat 和 @DateTimeFormat来进行数字和日期的格式化;
HttpMessageConverter(Http输入/输出转换器,比如JSON、XML等的数据输出转换器);
ContentNegotiatingViewResolver,内容协商视图解析器,它还是视图解析器,只是它支持根据请求信息将同一模型数据以不同的视图方式展示(如json、xml、html等),RESTful架构风格中很重要的概念(同一资源,多种表现形式);
Spring3 引入 一个 mvc XML的命名空间用于支持mvc配置,包括如:

自动注册基于注解风格的处理器需要的DefaultAnnotationHandlerMapping、AnnotationMethodHandlerAdapter
支持Spring3的ConversionService自动注册
支持JSR-303验证框架的自动探测并注册(只需把JSR-303实现放置到classpath)
自动注册相应的HttpMessageConverter(用于支持@RequestBody 和 @ResponseBody)(如XML输入输出转换器(只需将JAXP实现放置到classpath)、JSON输入输出转换器(只需将Jackson实现放置到classpath))等。
:注册自定义的处理器拦截器;
:和ParameterizableViewController类似,收到相应请求后直接选择相应的视图;
:逻辑静态资源路径到物理静态资源路径的支持;
:当在web.xml 中DispatcherServlet使用/ 映射时,能映射静态资源(当Spring Web MVC框架没有处理请求对应的控制器时(如一些静态资源),转交给默认的Servlet来响应静态文件,否则报404找不到资源错误,)。
Spring3.1新特性:
对Servlet 3.0的全面支持。
@EnableWebMvc:用于在基于Java类定义Bean配置中开启MVC支持,和XML中的功能一样;
新的@Contoller和@RequestMapping注解支持类:处理器映射RequestMappingHandlerMapping 和 处理器适配器RequestMappingHandlerAdapter组合来代替Spring2.5开始的处理器映射DefaultAnnotationHandlerMapping和处理器适配器AnnotationMethodHandlerAdapter,提供更多的扩展点,它们之间的区别我们在处理器映射一章介绍。
新的@ExceptionHandler 注解支持类:ExceptionHandlerExceptionResolver来代替Spring3.0的AnnotationMethodHandlerExceptionResolver,在异常处理器一章我们再详细讲解它们的区别。
@RequestMapping的”consumes” 和 “produces” 条件支持:用于支持@RequestBody 和 @ResponseBody,
1consumes指定请求的内容是什么类型的内容,即本处理方法消费什么类型的数据,如consumes=”application/json”表示JSON类型的内容,Spring会根据相应的HttpMessageConverter进行请求内容区数据到@RequestBody注解的命令对象的转换;
2produces指定生产什么类型的内容,如produces=”application/json”表示JSON类型的内容,Spring的根据相应的HttpMessageConverter进行请求内容区数据到@RequestBody注解的命令对象的转换,Spring会根据相应的HttpMessageConverter进行模型数据(返回值)到JSON响应内容的转换
URI模板变量增强:URI模板变量可以直接绑定到@ModelAttribute指定的命令对象、@PathVariable方法参数在视图渲染之前被合并到模型数据中(除JSON序列化、XML混搭场景下)。
@Validated:JSR-303的javax.validation.Valid一种变体(非JSR-303规范定义的,而是Spring自定义的),用于提供对Spring的验证器(org.springframework.validation.Validator)支持,需要Hibernate Validator 4.2及更高版本支持;
@RequestPart:提供对“multipart/form-data”请求的全面支持,支持Servlet 3.0文件上传(javax.servlet.http.Part)、支持内容的HttpMessageConverter(即根据请求头的Content-Type,来判断内容区数据是什么类型,如JSON、XML,能自动转换为命令对象),比@RequestParam更强大(只能对请求参数数据绑定,key-alue格式),而@RequestPart支持如JSON、XML内容区数据的绑定;详见本章的第×××节;
Flash 属性 和 RedirectAttribute:通过FlashMap存储一个请求的输出,当进入另一个请求时作为该请求的输入,典型场景如重定向(POST-REDIRECT-GET模式,1、POST时将下一次需要的数据放在FlashMap;2、重定向;3、通过GET访问重定向的地址,此时FlashMap会把1放到FlashMap的数据取出放到请求中,并从FlashMap中删除;从而支持在两次请求之间保存数据并防止了重复表单提交)。
Spring Web MVC提供FlashMapManager用于管理FlashMap,默认使用SessionFlashMapManager,即数据默认存储在session中。

SpringMVC常用注解:

@Controller
负责注册一个bean 到spring 上下文中
@Controller, @RestController都是用来表示spring某个类的是否可以接收HTTP请求,区别是@Controller是标识一个Spring类是Spring MVC controller处理器,而@RestController是@Controller和@ResponseBody的结合体。
@RestController:a convenience annotation that does nothing more than adding the @Controller and @ResponseBody annotations。
参考http://blog.csdn.net/alan_liuyue/article/details/53837127

@RequestMapping
注解为控制器指定可以处理哪些 URL 请求

@RequestBody
该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上 ,再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上

@ResponseBody
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区

@ModelAttribute
在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法

在方法的入参前使用 @ModelAttribute 注解:可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数 –绑定到对象中,再传入入参将方法入参对象添加到模型中

@RequestParam
在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法,如果参数名和变量名不一致,可以使用@RequestParam(name),告诉spring,使用指定名字入参。
@RequestParam(value = “name”, defaultValue = “https://my.oschina.net/gaussik/blog/World”)
Spring入门基础 @RequestParam必须要加上参数名 https://my.oschina.net/zhukp/blog/173042

@PathVariable
绑定 URL 占位符到入参

@ExceptionHandler
注解到方法上,出现异常时会执行该方法

@ControllerAdvice
使一个Contoller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常

配置tomcat
选下载安装tomcat,然后在eclipse偏好设置中找到”server“菜单下的”Runtime Environment“,之后在此页面下点击”add“,选择”tomcat6.0“之后,点击”Next“,点击”Browse“之后找到”Tomcat“的存储路径,点击”Finsh“即可完成。

JAVA配置和注解配置的区别
http://blog.csdn.net/durendong/article/details/54566027

spring注解

Spring2.5引入了 @Autowired 注释,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 在spring的bean配置中会按照byType或byName来自动装配,不必配置属性,不再需要 set ,get方法。
http://swiftlet.net/archives/734

spring boot文档

http://docs.spring.io/spring-boot/docs/current/reference/html/
SpringBoot开发详解(一)–初识SpringBoot

Spring Cloud文档

《Spring Cloud微服务实战》
http://blog.didispace.com/
http://blog.csdn.net/forezp/article/category/6830968
http://blog.csdn.net/u010066934/article/details/54232622

Spring Cloud 文档
http://cloud.spring.io/spring-cloud-static/spring-cloud.html#_features

Spring Boot

Spring Boot

Springboot本身默认的执行方式是单线程同步执行,并行需手动配置参数。

Spring Boot中实现异步调用
http://blog.csdn.net/qq_26562641/article/details/53332495

HttpClient的3种超时
http://blog.csdn.net/hudashi/article/details/8652482

Spring-Boot-Reference-Guide
https://qbgbook.gitbooks.io/spring-boot-reference-guide-zh/

运行TEST:打开Test代码文件,右键或run菜单中就变成test了。

Spring Boot热部署
http://www.imooc.com/learn/915

Spring Cloud

Spring官方在spring boot的基础上,封装了Netflix相关组件,提供了一个名为Spring Cloud的开源项目。

RestTemplate

RestTemplate 调用传参
http://blog.csdn.net/itlqi/article/details/49592985

Spring Boot中访问数据库

1.使用JdbcTemplate访问数据库
2.使用Spring-data-jpa整合orm框架访问数据库

Spring-mongodb

Spring-mongodb 查询
http://docs.spring.io/spring-data/mongodb/docs/1.2.0.RELEASE/reference/html/mongo.repositories.html
http://blog.csdn.net/congcong68/article/details/47183209

Spring Data与MongoDB:不协调的设计,及评论
http://www.infoq.com/cn/news/2013/11/spring-data-mongo-mismatch

MONGODB中的分组聚合在JAVA中的用法
http://www.debugrun.com/a/1pcWFsT.html

Swagger

Swagger使用指南
https://my.oschina.net/dlam/blog/808315

Spring boot项目,使用maven打包包含本地jar
http://www.jianshu.com/p/4f88837945c9

缓存

@Cacheable标注的方法,如果其所在的类实现了某个接口,那么该标注所在方法也必须出现在接口里面,否则cache无效。
具体的原因是, Spring把实现类装载成为Bean的时候,会用代理包装一下,所以从Spring Bean的角度看,只有接口里面的方法是可见的,其它的都隐藏了,看不到实现类里面的非接口方法,@Cacheable不起作用。
解决办法:把待cache的方法移到接口里面,或者把@Cacheable标注在一个没有实现任何接口的类的public方法上。因为这种Bean也被Spring产生了代理, 看得到的只有public方法。
Spring 在执行 @Cacheable 标注的方法前先查看缓存中是否有数据,如果有数据,则直接返回缓存数据,不再执行方法体;若没有数据,执行该方法并将方法返回值放进缓存。