Content Table

Setter 注入

CommonUtils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.xtuer.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;

public class CommonUtils {
private static DefaultPrettyPrinter printer;
static {
// Setup a pretty printer with an indenter (indenter has 4 spaces in this case)
DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(" ", DefaultIndenter.SYS_LF);
printer = new DefaultPrettyPrinter();
printer.indentObjectsWith(indenter);
printer.indentArraysWith(indenter);
}

/**
* 以 Json 的格式输出对象
* @param obj
*/
public static void output(Object obj) {
ObjectMapper mapper = new ObjectMapper();

try {
// 默认用 2 个空格缩进
// System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj));

// 自定义缩进,用 4 个空格
System.out.println(mapper.writer(printer).writeValueAsString(obj));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}

ID Name Alias

id, name, alias

  • 每个 Bean 都有标志符,用这个标志符从 Spring IoC Container 里获取 Bean
  • id, name, alias 都必须在 IoC 容器里唯一
  • 每个 Bean 可以有一个 id 属性,并可以根据该 id 在 IoC 容器中查找该 Bean,该 id 属性值必须在 IoC 容器中唯一
  • 如果不指定 id,只指定 name,那么 name 为 Bean 的标识符,并且需要在容器中唯一
  • 同时指定 name 和 id,此时 id 为标识符,而 name 为 Bean 的别名,两者都可以找到目标 Bean
  • 可以指定多个 name,之间可以用分号 ;、空格 或逗号 , 分隔开,如果没有指定 id,那么第一个 name 为标识符,其余的为别名;若指定了 id 属性,则 id 为标识符,所有的 name 均为别名
  • 可以使用 <alias> 标签指定别名,别名也必须在 IoC 容器中唯一
  • 如果 id 和 name 都不指定,那么 Spring 容器会为 Bean 生成一个 id,生成规则:
    按 Bean 定义的顺序,在类的全路径名加上 #序号 (序号从 0 开始,第一个 bean 的别名是类的全路径名,所以可以使用类的全路径名来获取),如:
    com.xtuer.beans.User#0 (com.xtuer.beans.User)
    com.xtuer.beans.User#1
    com.xtuer.beans.User#2
    com.xtuer.beans.User#3

Spring IoC Introduction

IoC 是什么?

控制反转(Inversion of Control,英文缩写为 IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的 Spring 框架的核心。 控制反转一般分为两种类型,依赖注入(Dependency Injection,简称 DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛。

应用控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体(Spring IoC Container)将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。所以,控制反转是,关于一个对象如何获取他所依赖的对象的引用,这个责任的反转。

对象的生成不再是在代码里用 new 创建的,而是在 XML 里定义对象之间的依赖关系,然后由 Spring 来生成对象。

IoC 最大的好处是什么?

  • 因为把对象生成放在了 XML 里定义,所以当我们需要换一个实现子类将会变成很简单(一般这样的对象都是实现于某种接口的),只要修改 XML 就可以了,这样我们甚至可以实现对象的热插拔(有点像 USB 接口和 SCSI 硬盘了)。

IoC 最大的缺点是什么?

  • 生成一个对象的步骤变复杂了(事实上操作上还是挺简单的),对于不习惯这种方式的人,会觉得有些别扭和不直观。
  • 对象生成因为是使用反射编程,在效率上有些损耗。但相对于 IoC 提高的维护性和灵活性来说,这点损耗是微不足道的,除非某对象的生成对效率要求特别高。
  • 缺少 IDE 重构操作的支持,如果在 Eclipse 要对类改名,那么你还需要去XML文件里手工去改了,这似乎是所有 XML 方式的缺憾所在。

Spring Hello World

项目的结构图

spring-beans.xml

叫做 Bean configuration file,定义 bean 的属性和其他 bean 之间的依赖,Spring 根据 bean 的定义生成 bean。

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="userDao" class="com.xtuer.dao.UserDaoMySqlImpl"/>
</beans>

压力测试

下面介绍使用 Apache 的 ab (Apache Benchmark) 简单的进行压力测试

主要参数:

  • -n: 总请求数
  • -c: 并发用户数
  • -C: cookie

测试:

1
ab -n1000 -c30 http://localhost:8080/demo

Nginx 负载均衡

通过简单的配置,Nginx 可以实现反向代理,负载均衡,动静分离,URL 重写等。

代理

  • 正向代理:客户使用代理访问多个外部 Web 服务器,就是翻墙
  • 反向代理:多个客户使用它访问内部 Web 服务器

Miscellaneous

RequestMapping

Since introduction of RequestMappingHandlerMapping and RequestMappingHandlerAdapter in Spring 3.1 the distinction is even simpler: RequestMappingHandlerMapping finds the appropriate handler method for the given request. RequestMappingHandlerAdapter executes this method, providing it with all the arguments.

mvc:view-controller

有很多静态页面,里没有动态的内容,如果写 Controller 去做映射的话又感觉很麻烦,都是体力活,没什么意思,这时可以用 mvc:view-controller 进行映射达到相同的效果而又不需要写 Controller。

1
2
<!-- result.htm 是 View 的名字 -->
<mvc:view-controller path="/xtuer" view-name="result.htm"/>

访问 http://localhost/xtuer,则 View Resolver 访问的是 /WEB-INF/view/ftl/result.htm

防止表单重复提交

开始介绍使用 redirect 技术防止表单提交,但是 redirect 解决不了后退到表单页面时重复提交表单,为了解决这个问题,加入了 token 的机制,而且同时能够防止 CRSF 攻击。

Token 的生成和校验也有不同的方式,如果每个 form 相关的处理方法中都写一遍 token 的生成和校验代码,在实际项目中是不太能接受的,文章的后面介绍了使用拦截器的方式生成和校验 token,这种方式在实际项目里才有意义。

SpringMVC 事务

事务具有以下四个基本特征

Name Description
Atomic(原子性) 事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。
Consistency(一致性) 只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。
Isolation(隔离性) 事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。
同时,并行事务的修改必须与其他并行事务的修改相互独立。
Durability(持久性) 事务结束后,事务处理的结果必须能够得到固化。数据库肯定是要被广大客户所共享访问的,
那么在数据库操作过程中很可能出现以下几种不确定情况。