C标准库参考指南(上)

前述

c标准库参考指南
A guide to the stranded C library

本指南主要基于《C标准库》(P.J.Plauger,2009-7-1,人民邮电出版社),在用到c标准库的时候可以参考,同时本指南也有部分实现细节。由于时间和精力有限,很多方面被忽略掉了,比如硬件相关部分、区域化设置、大部分数学函数、内存分配算法、宽字符和多字符部分、其他复杂的算法等。

东方肖遥
185442111@qq.com
http://weibo.com/u/1901302255
http://blog.csdn.net/liuyuan185442111
2014年9-10月 于北邮

v1.1,稍微做了一些修改,2015年2月,于家
v1.2,稍作修改,2015年6月,于学校
v1.3,稍加整理格式,以作备份,2017年9月,于公司

最初c89标准库只有15个头文件:

头文件说明
assert.h断言相关
ctype.h字符类型判断
errno.h标准错误机制
float.h浮点限制
limits.h整型限制
locale.h本地化接口
math.h数学函数
setjmp.h非本地跳转
signal.h信号相关
stdarg.h可变参数处理
stddef.h一些宏和类型的定义
stdio.h标准I/O库
stdlib.h标准工具库
string.h字符串及内存处理
time.h时间相关

后来标准库扩充了一些,但这15个无疑是最常用的,《C标准库》一书也仅介绍了这15个头文件,在此我也仅介绍这15个头文件。

断言(assert.h)

此头文件只包含一个assert宏,从用法上看它十分类似一个返回值是void的函数。如果条件为假,assert将输出一些信息并调用abort函数退出程序。
一个可能的实现:

#ifdef NDEBUG
#define assert(x) ((void)0)
#else
void _assert(const char*, const char*, int);
#define assert(e) ((e) ? (void)0 : _assert(#e, __FILE__, __LINE__))
#endif

assert应该只用在debug版本中。如果#define NDEBUG,之后的assert将会失效;可以重新#undef NDEBUG,但需要再次#include assert.h才能使后面的assert生效。
因为需要被多次include,所以本头文件不需要通过“#ifndef机制”防止被多次包含。

字符类型判断(ctype.h)

此头文件定义了一批c语言字符分类函数。
以下假定使用的字符集是ASCII。
这些函数都只有一个参数,且参数和返回值均为int类型,比如int isalpha(int);
为了提高速度,很多函数的实现可能会采用查表法,在这里只描述其功能,而不细述其实现。
下表列出了这些函数:
函数说明

标准错误机制(errno.h)

此头文件定义了一个表示错误信息的errno,errno等价于一个全局整型变量。
另外还定义了表示错误编码的一些宏,他们都以”E”开头。比如:
错误编码

浮点限制(float.h)

此头文件定义了浮点型变量的一些极限值和设置。

整型限制(limits.h)

此头文件定义了整型变量的一些极限值和设置。

本地化(locale.h)

c语言支持本地化设定,如本地格式时间和货币符号。
此头文件包含一个类型定义,两个函数声明和一些宏定义。

类型定义

struct lconv;

其成员中有三个会影响浮点数的表达形式:

char *decimal_point; // 格式化非货币量中的小数点字符
char *thousands_sep; // 用来对格式化的非货币量中小数点前面的数字进行分组的字符
char *grouping; // 用来说明格式化的非货币量中每一组数字的数目

其他成员影响货币的表达形式。

函数声明

struct lconv *localeconv(void);

标准库定义了一个struct lconv类型的全局变量,此函数返回指向此变量的指针。

char *setlocale(int category, const char *locale);

此函数用来设定或恢复本地化配置。
其中category参数可以为LC_COLLATE,LC_CTYPE,LC_MONETARY,LC_NUMERIC,LC_TIME,LC_ALL。

参数说明
LC_ALL设置所有信息
LC_COLLATE影响strcoll和strxfrm函数
LC_CTYPE影响所有字符函数
LC_MONETARY影响由localeconv函数提供的货币信息
LC_NUMERIC影响十进制小数格式和localeconv函数提供的信息
LC_TIME影响strftime函数

如果locale是一个指向字符串的指针且选择有效,则返回一个和新的区域设置指定的category相联系的字符串的指针;如果选择因故无法实现,则返回一个空指针且程序的区域设置不改变。如果locale参数是一个空指针,则返回一个和当前区域设置的category相联系的字符串的指针,程序的区域设置不改变。
"C"为编译器指定的最小环境值,""指定了实现定义的本地环境,在程序启动时,程序执行与“setlocale(LC_ALL, "C");”等效的代码。

此外,本文件还定义了NULL宏。gcc是这样说的:According to C89 std, NULL is defined in locale.h too。

经测试,decimal_point的值会影响gcc中printf输出中的小数点,vc下无影响,thousands_sep和grouping不会对printf产生影响。

数学函数(math.h)

此头文件里的函数都是由专业人士编写,普通用户只需要了解怎么用就可以了。
此头文件定义了一个宏HUGE_VAL,它展开为一个正的double类型的表达式。
还声明了一些数学函数,除了frexp、ldexp、modf,其他函数的参数和返回值都是double类型。

数学函数常会发生定义域错误和值域错误:
如发生定义域错误,errno设为EDOM。
如发生值域错误:如果结果上溢,函数返回HUGE_VAL的值,符号与函数的正确值相同(除了tan函数),errno设为ERANGE;如果结果下溢,函数返回0,errno是否取宏ERANGE的值取决于实现。

大部分函数的用法显而易见,所以仅把这些函数的声明列出来,对另外一些函数则进行详细说明。

三角函数和双曲函数

double sin(double x);
double cos(double x);
double tan(double x);
double asin(double x);
double acos(double x);
double atan(double x);
double atan2(double y, double x);
double sinh(double x);
double cosh(double x);
double tanh(double x);

指数函数、对数函数、幂函数

double exp(double x); // e的x方
double log(double x); // 自然对数
double log10(double x); // 以10为底x的对数
double pow(double x, double y); //x的y次方
double sqrt(double x); // x的平方根

double frexp(double value, int *exp);

此函数把一个浮点数分为一个规格化小数和一个2的整数幂。假定返回值为x,x的范围为[1/2,1),或者为0。参数和返回值满足value=x*2^exp,如果value为0,x和*exp都为0。

double ldexp(double x, int exp);

此函数计算一个浮点数和2的整数幂的乘积,它返回x*2^exp的值。

double modf(double value, double *iptr);

此函数把value分为整数和小数部分,他们的符号和value的符号相同,小数部分作为返回值,整数部分存放在iptr指向的double类型的对象中。

取整函数、绝对值函数、取余函数

double ceil(double x); // 不小于x的最小整数,ceil天花板。
double floor(double x); // 不大于x的最大整数,floor地板。
double fabs(double x); // x的绝对值
double fmod(double x, double y); // x除以y的浮点余数

非本地跳转(setjmp.h)

此头文件包含:

typedef int jmp_buf[16];
int setjmp(jmp_buf);
void longjmp(jmp_buf, int);

setjmp和longjmp可能实现为宏定义。
非本地跳转的原理非常简单:
1.setjmp(j)设置“jump”点,用正确的程序上下文填充jmp_buf对象j。这个上下文包括程序存放位置,栈和框架指针,其它重要的寄存器和内存数据。当初始化完jump的上下文,setjmp()返回0值。
2.以后调用longjmp(j,r)的效果就是一个非局部的goto或“长跳转”到由j描述的上下文处(也就是原来调用setjmp(j)处)。当作为长跳转的目标而被调用时,setjmp()返回r或1(如果r设为0的话)。(记住,setjmp()不能在这种情况时返回0)
通过有两类返回值,setjmp()让你知道它正在被怎么使用。当设置j时,setjmp()如你期望地执行;但当作为长跳转的目标时,setjmp()就从外面“唤醒”它的上下文。可以将longjmp()用来终止异常,用setjmp()标记相应的异常处理程序。

信号(signal.h)

此头文件包含两个函数和一些宏定义。
核心是两个函数:

void ( *signal( int signum, void (*handler)(int) ) )(int);
或
typedef void (*sig_t)(int);
sig_t signal(int signum, sig_t handler);
int raise(int signum);

signal函数

signal函数用来设置某一信号的对应动作。
执行成功,返回旧handler的指针;否则,返回SIG_ERR。
第一个参数signum指明了所要处理的信号类型,应使用后面说明的信号编号宏定义。
第二个参数handler描述了与信号相关联的动作,它可以取以下三种值:
(1)一个无返回值的函数指针
此函数必须在signal函数被调用前申明,handler为这个函数的名字。当接收到一个编号为signum的信号时,就执行handler所指定的函数。这个函数应有如下形式的定义:void func(int sig);。
(2)SIG_IGN
这个符号表示忽略该信号。
(3)SIG_DFL
这个符号表示恢复系统对该信号的默认处理。
When signal handler is set to a function and a signal occurs, it is implementation defined whether signal(sig, SIG_DFL); will be executed immediately before the start of signal handler. Also, the implementation can prevent some implementation-defined set of signals from occurring while the signal handler runs.

raise函数用来把信号signum送给正在执行的程序。
执行成功,返回0;否则,返回非零。

还有一些宏定义

// signal return values
#define SIG_DFL ((void(*)(int)) 0)
#define SIG_IGN ((void(*)(int)) 1)
#define SIG_ERR ((void(*)(int)) -1)

// signal codes
#define SIGINT      2 // Interactive attention
#define SIGILL      4 // Illegal instruction
#define SIGFPE      8 // Floating point error
#define SIGSEGV     11 // Segmentation violation
#define SIGTERM     15 // Termination request
#define SIGABRT     22 // Abnormal termination (abort)

信号编号
SIGINT,收到一个交互的提示信号,当用户按下Ctrl-C会产生一个SIGINT信号。
SIGILL,检测到无效的函数映像,比如一条非法指令。
SIGFPE,错误的算术操作,比如除零或者导致溢出的操作。
SIGSEGV,对存储器的无效访问,向一个空指针写数据会产生一个SIGSEGV信号。
SIGTERM,送到程序的终止请求。
SIGABRT,异常终止,比如执行了abort函数。

注意

并不一定非要调用raise函数才会释放相应的信号,比如当按下ctrl-c时,并没有调用raise,但系统会产生一个SIGINT信号。

另外,此头文件还定义了sig_atomic_t这个类型,An integer type which can be accessed as an atomic entity even in the presence of asynchronous interrupts made by signals。

可变参数表列(stdarg.h)

此头文件定义了三个宏和一个类型。
这个类型是va_list,它可能被实现为char*的typedef。
这三个宏都在拥有可变参数的函数定义里被调用,下面的ap是一个va_list类型的变量。

va_start(ap,A)

A是参数表列里…之前的最后一个参数,执行完此语句,ap会指向A之后的下一个参数(也就是可变参数中的第一个参数);

av_arg(ap,T)

T是对应参数的类型,执行完此语句,ap会指向下一个参数;

va_end(ap)

释放ap,不过在一些实现里,被定义成void(0)。

这个机制基于如下(但不仅限于)假设:
一个可变参数表在内存中占据了一个连续的字符数组;
后继的参数占据着字符数组更高位的后继元素;
2^N字节对齐;
参数表列里有一个指示参数数目的参数或有一个指示参数表列结束的标志。

标准定义(stddef.h)

此头文件定义了3个类型和2个宏,其中一些在其他头文件中也有定义。

这3个类型是:
ptrdiff_t:两个指针相减的结果的类型,有符号整型,一般来说是int或long的typedef。
size_t:是sizeof操作符的结果的类型,无符号整型,一般来说定义成unsigned int或unsigned long,但应与ptrdiff_t相对应。
wchar_t:是一个整型,标识一个宽字节字符,例如L'x'的类型就是wchar_t。

这2个宏是:
NULL:空指针常量。
offsetof(type, member-designator):展开为一个size_t类型的整值常量表达式,它的值是从结构的起始位置到结构成员的偏移量,以字节为单位。

本头文件一个可能的实现:

#ifndef _STDDEF
#define _STDDEF

typedef unsigned int size_t;
typedef unsigned short wchar_t;
typedef int ptrdiff_t;
#define NULL (void *)0
#define offsetof(T, member) ((size_t)&((T *)0)->member)

#endif // _STDDEF

标准工具库(stdlib.h)

此头文件定义了4种类型和几个宏。
size_t和wchar_t在stddef.h里也有定义。
div_t是一个结构类型,是函数div的返回值的类型,ldiv_t也是一个结构类型,是函数ldiv的返回值类型。

定义的宏:
NULL。
EXIT_FAILURE,EXIT_SUCCESS,它们展开为整值常量表达式,可作为exit函数的参数使用,分别返回给宿主环境不成功和成功终止的状态。
RAND_MAX展开为整值常量表达式,其值是rand函数返回的最大值。
MB_CUR_MAX展开为整值常量表达式,其值是当前区域设置指定的扩展字符集中多字节字符的最大字节数目。

本文件还声明了诸多函数。分类如下:
 整型数学
执行简单的整型算术:abs,div,labs,ldiv
 算法
复杂而又被广泛使用、足以打包作为库函数的操作:bsearch,qsort,rand,srand
 文本转换
确定文本表示的编码算术值:atof,atoi,atol,strtod,strtol,strtoul
 多字节转换
多字节和宽字节字符编码之间的转换:mblen,mbstowcs,mbtowc,wcstombs,wctomb
 存储分配
管理数据对象的堆:calloc,free,malloc,realloc
 环境接口
程序和执行环境之间的接口:abort,atexit,exit,getenv,system

生成随机数

int rand(void);

返回一个伪随机整数,范围在0到RAND_MAX之间(包括0和RAND_MAX)。

void srand(unsigned int seed);

以seed初始化随机数发生器,这个种子默认为1,也就是说如果在调用rand之前不调用srand,相当于调用了“srand(1);”。

绝对值和整数除法

int abs(int j);
long int labs(long int j);
div_t div(int number, int denom);
ldiv_t ldiv(long int number, long int denom);

div_t有两个成员,int quot和int rem,分别用来保存number除以denom的商和余数。
相比div_t,ldiv_t的两个成员的类型只是都变成long int而已。

内存管理

void *malloc(size_t size);

为一个对象分配空间,该对象的大小是size。如果失败返回空指针。

void free(void *ptr);

ptr如果是空指针,不发生任何行为;其他不适当的参数会导致未定义的行为。

void *calloc(size_t nmemb, size_t size);

为拥有nmemb个元素的数组分配空间,每一个元素的大小是size,数组将被初始化为0。分配失败返回空指针。

void *realloc(void *ptr, size_t size);

将ptr指向的对象的大小改变为由size指定的大小。如果ptr是一个空指针,与malloc行为相同;如果size为0且ptr不是空指针,与free行为相同。

字符转换函数

int atoi(const char *nptr);

除了出错后的行为,它等价于(int)strtol(nptr, (char **)NULL, 10);

long int atol(const char *nptr);

除了出错后的行为,它等价于strtol(nptr, (char **)NULL, 10);

double atof(const char *nptr);

把nptr指向的字符串的初始部分转换为double类型的表示。除了出错后的行为,它等价于strtod(nptr, (char **)NULL);

long int strtol(const char *nptr, char **endptr, int base);

如果存在转换后的值,则返回这个值。如果没有执行转换,则返回0。如果正确的转换值在可表示的范围值外,则返回LONG_MAX或者LONG_MIN,并将宏ERANGE的值存储在errno中。

unsigned long int strtoul(const char *nptr, char **endptr, int base);

如果存在转换后的值,则返回这个值。如果没有执行转换,则返回0。如果正确的转换值在可表示的范围值外,则返回ULONG_MAX,并将宏ERANGE的值存储在errno中。

double strtod(const char *nptr, char **endptr);

它把输入串分解为3个部分:可能为空的初始序列,由一些空白字符组成(由isspace函数指定);目标序列;一个或多个不能识别的字符组成的序列,包括输入串结尾的空字符。目标序列的期望形式是:-5.3e-3,起始字符可以是正负符号,可以是0-9,可以是小数点。
如果存在转换后的值,则返回这个值。如果没有执行转换,则返回0。如果正确的转换值在可表示的范围值外,则返回正或者负的HUGE_VAL,并将宏ERANGE的值存储在errno中。如果正确的转换值会造成下溢,则返回0,并将宏ERANGE的值存储在errno中。
如果endptr不为空,则指向最后串的指针存储在endptr指向的对象中。

附函数strtol可能的实现代码:

#include <errno.h>
#include <limits.h>
int isspace(int c)
{
    if(c >=9 && c <= 12 || c == 32) return 1;
    return 0;
}
int tolower(int c)
{
    if(c >= 65 && c <= 90) c += 32;
    return c;
}

#define BASE_MAX 36 // 可接受的最大进制
static const char digits[] =
{"0123456789abcdefghijklmnopqrstuvwxyz"};

long strtol(const char *s, char **endptr, int base)
{
    const char *sc = s;
    long y, x = 0; // 临时变量

    while(isspace(*sc)) ++sc; // 跳过空白

    char sign = *sc == '-' || *sc == '+' ? *sc++ : '+'; // 记录符号

    if(base < 2 || BASE_MAX < base) // 检查进制
    {
        if(endptr) *endptr = (char *)s;
        return 0;
    }
    else if(*sc == '0' && (sc[1] == 'x' || sc[1] == 'X')) // 跳过16进制下开头的0x
    {
        if(base != 16)
        {
            if(endptr) *endptr = (char *)s;
            return 0;
        }
        sc += 2;
    }

    for(; *sc == '0'; ++sc); // 跳过0

    for(const char *sd; (sd = (const char *)memchr(digits, tolower(*sc), base)) != NULL; ++sc)
    {
        y = x; // 记录本次x
        x = x * base + (sd - digits);
    }

    ptrdiff_t rem = (const char *)memchr(digits, tolower(*(sc-1)), base) - digits;
    if((x - rem) / base != y) // 测试是否溢出
    {
        errno = ERANGE;
        if(sign == '+') x = LONG_MAX;
        else x = LONG_MIN, sign = '+';
    }

    if(sign == '-') x = -x;
    if(endptr) *endptr = (char *)sc;

    return x;
}

查找和排序

void qsort(void *base, size_t nmemb, size_t size, int (*compare)(const void *, const void *));

根据compare所指向的比较函数将数组内容排列成升序。如果第一个元素小于、等于或大于第二个元素,compare分别返回小于0,等于0和大于0的整数。
数组的大小为nmemb,每个元素的大小为size,base指向第一个元素。

void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compare)(const void *, const void *));

搜索一个拥有nmemb个元素的数组,来查找与key指向的对象匹配的元素,base指向这个数组的第一个元素。数组中的每个元素的大小由size指定。
如果有多个元素命中,可能返回指向任一个的指针。
compare的第一个参数指向key数据,第二个参数指向一个数组元素。
要保证数组必须是非降序排列的。

环境通信函数

int atexit(void (*func)(void));

注册func指向的函数,该函数在程序正常终止的时候被调用。成功返回0,否则返回非0。实现应该至少支持32个函数的注册,一个函数可以注册多次。

void exit(int status);

使程序正常终止。
首先,调用所有atexit注册的函数,按照他们注册时的反顺序调用。
然后,清空所有打开的具有未写缓冲数据的流,关闭所有打开的流,并删除tmpfile函数创建的所有文件。
最后,控制权返回给宿主环境。

void abort(void);

使程序异常终止,除非捕获了信号SIGABRT且信号处理程序没有返回。可能会实现为调用exit函数并释放SIGABRT信号。

char *getenv(const char *name);

搜索宿主环境提供的环境表,来查找一个能和name指向的串匹配的串。如果不能找到,则返回空指针。也就是windows下的环境变量。

int system(const char *string);

把sring指向的串传递给宿主环境,然后命令处理程序按照实现定义的方式执行它,可以使用空指针作为参数查询命令处理程序是否存在。如果参数是空指针,只有当命令处理程序可用的时候返回非0。如果参数不是空指针,返回一个实现定义的值。

多字节字符和多字节串函数

这些函数的行为受当前区域设置类别LC_CTYPE的影响,在此仅列出:

int mblen(const char *s, size_t n);
int mbtowc(wchar_t *pwc, const char *s, size_t n);
int wctomb(char *s, wchar_t wchar);
size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n);
size_t wcstombs(char *s, const wchar_t *pwcs, size_t n);
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 介紹 2. I. Spring Boot文档 i. 1. 关于本文档 ii. 2. 获取帮助 iii. 3. 第一步 iv. 4. 使用Spring Boot v. 5. 了解Spring Boot特性 vi. 6. 迁移到生存环境 vii. 7. 高级主题 3. II. 开始 i. 8. Spring Boot介绍 ii. 9. 系统要求 i. 9.1. Servlet容器 iii. 10. Spring Boot安装 i. 10.1. 为Java开发者准备的安装指南 i. 10.1.1. Maven安装 ii. 10.1.2. Gradle安装 ii. 10.2. Spring Boot CLI安装 i. 10.2.1. 手动安装 ii. 10.2.2. 使用GVM安装 iii. 10.2.3. 使用OSX Homebrew进行安装 iv. 10.2.4. 使用MacPorts进行安装 v. 10.2.5. 命令行实现 vi. 10.2.6. Spring CLI示例快速入门 iii. 10.3. 从Spring Boot早期版本升级 iv. 11. 开发你的第一个Spring Boot应用 v. 11.1. 创建POM vi. 11.2. 添加classpath依赖 vii. 11.3. 编写代码 i. 11.3.1. @RestController和@RequestMapping注解 ii. 11.3.2. @EnableAutoConfiguration注解 iii. 11.3.3. main方法 viii. 11.4. 运行示例 ix. 11.5. 创建一个可执行jar x. 12. 接下来阅读什么 4. III. 使用Spring Boot i. 13. 构建系统 i. 13.1. Maven i. 13.1.1. 继承starter parent ii. 13.1.2. 使用没有父POM的Spring Boot iii. 13.1.3. 改变Java版本 iv. 13.1.4. 使用Spring Boot Maven插件 ii. 13.2. Gradle iii. 13.3. Ant iv. 13.4. Starter POMs ii. 14. 组织你的代码 i. 14.1. 使用"default"包 ii. 14.2. 定位main应用类 iii. 15. 配置类 目錄 Spring Boot参考指南 2 i. 15.1. 导入其他配置类 ii. 15.2. 导入XML配置 iv. 16. 自动配置 i. 16.1. 逐步替换自动配置 ii. 16.2. 禁用特定的自动配置 v. 17. Spring Beans和依赖注入 vi. 18. 使用@SpringBootApplication注解 vii. 19. 运行应用程序 i. 19.1. 从IDE中运行 ii. 19.2. 作为一个打包后的应用运行 iii. 19.3. 使用Maven插件运行 iv. 19.4. 使用Gradle插件运行 v. 19.5. 热交换 viii. 20. 打包用于生产的应用程序 ix. 21. 接下来阅读什么 5. IV. Spring Boot特性 i. 22. SpringApplication i. 22.1. 自定义Banner ii. 22.2. 自定义SpringApplication iii. 22.3. 流畅的构建API iv. 22.4. Application事件和监听器 v. 22.5. Web环境 vi. 22.6. 命令行启动器 vii. 22.7. Application退出 ii. 23.外化配置 i. 23.1. 配置随机值 ii. 23.2. 访问命令行属性 iii. 23.3. Application属性文件 iv. 23.4. 特定的Profile属性 v. 23.5. 属性占位符 vi. 23.6. 使用YAML代替Properties i. 23.6.1. 加载YAML ii. 23.6.2. 在Spring环境中使用YAML暴露属性 iii. 23.6.3. Multi-profile YAML文档 iv. 23.6.4. YAML缺点 vii. 23.7. 类型安全的配置属性 i. 23.7.1. 第三方配置 ii. 23.7.2. 松散的绑定(Relaxed binding) iii. 23.7.3. @ConfigurationProperties校验 iii. 24. Profiles i. 24.1. 添加激活的配置(profiles) ii. 24.2.以编程方式设置profiles iii. 24.3. Profile特定配置文件 iv. 25. 日志 i. 25.1. 日志格式 ii. 25.2. 控制台输出 iii. 25.3. 文件输出 iv. 25.4. 日志级别 v. 25.5. 自定义日志配置 v. 26. 开发Web应用 i. 26.1. Spring Web MVC框架 i. 26.1.1. Spring MVC自动配置 ii. 26.1.2. HttpMessageConverters Spring Boot参考指南 3 iii. 26.1.3. MessageCodesResolver iv. 26.1.4. 静态内容 v. 26.1.5. 模板引擎 vi. 26.1.6. 错误处理 vii. 26.1.7. Spring HATEOAS ii. 26.2. JAX-RS和Jersey iii. 26.3. 内嵌servlet容器支持 i. 26.3.1. Servlets和Filters ii. 26.3.2. EmbeddedWebApplicationContext iii. 26.3.3. 自定义内嵌servlet容器 iv. 26.3.4. JSP的限制 vi. 27. 安全 vii. 28. 使用SQL数据库 i. 28.1. 配置DataSource i. 28.1.1. 对内嵌数据库的支持 ii. 28.1.2. 连接到一个生产环境数据库 iii. 28.1.3. 连接到一个JNDI数据库 ii. 28.2. 使用JdbcTemplate iii. 28.3. JPA和Spring Data i. 28.3.1. 实体类 ii. 28.3.2. Spring Data JPA仓库 iii. 28.3.3. 创建和删除JPA数据库 viii. 29. 使用NoSQL技术 i. 29.1. Redis i. 29.1.1. 连接Redis ii. 29.2. MongoDB i. 29.2.1. 连接MongoDB数据库 ii. 29.2.2. MongoDBTemplate iii. 29.2.3. Spring Data MongoDB仓库 iii. 29.3. Gemfire iv. 29.4. Solr i. 29.4.1. 连接Solr ii. 29.4.2. Spring Data Solr仓库 v. 29.5. Elasticsearch i. 29.5.1. 连接Elasticsearch ii. 29.5.2. Spring Data Elasticseach仓库 ix. 30. 消息 i. 30.1. JMS i. 30.1.1. HornetQ支持 ii. 30.1.2. ActiveQ支持 iii. 30.1.3. 使用JNDI ConnectionFactory iv. 30.1.4. 发送消息 v. 30.1.5. 接收消息 x. 31. 发送邮件 xi. 32. 使用JTA处理分布式事务 i. 32.1. 使用一个Atomikos事务管理器 ii. 32.2. 使用一个Bitronix事务管理器 iii. 32.3. 使用一个J2EE管理的事务管理器 iv. 32.4. 混合XA和non-XA的JMS连接 v. 32.5. 支持可替代的内嵌事务管理器 xii. 33. Spring集成 xiii. 34. 基于JMX的监控和管理 xiv. 35. 测试 Spring Boot参考指南 4 i. 35.1. 测试作用域依赖 ii. 35.2. 测试Spring应用 iii. 35.3. 测试Spring Boot应用 i. 35.3.1. 使用Spock测试Spring Boot应用 iv. 35.4. 测试工具 i. 35.4.1. ConfigFileApplicationContextInitializer ii. 35.4.2. EnvironmentTestUtils iii. 35.4.3. OutputCapture iv. 35.4.4. TestRestTemplate xv. 36. 开发自动配置和使用条件 i. 36.1. 理解auto-configured beans ii. 36.2. 定位auto-configuration候选者 iii. 36.3. Condition注解 i. 36.3.1. Class条件 ii. 36.3.2. Bean条件 iii. 36.3.3. Property条件 iv. 36.3.4. Resource条件 v. 36.3.5. Web Application条件 vi. 36.3.6. SpEL表达式条件 xvi. 37. WebSockets xvii. 38. 接下来阅读什么 6. V. Spring Boot执行器: Production-ready特性 i. 39. 开启production-ready特性 ii. 40. 端点 i. 40.1. 自定义端点 ii. 40.2. 健康信息 iii. 40.3. 安全与HealthIndicators i. 40.3.1. 自动配置的HealthIndicators ii. 40.3.2. 编写自定义HealthIndicators iv. 40.4. 自定义应用info信息 i. 40.4.1. 在构建时期自动扩展info属性 ii. 40.4.2. Git提交信息 iii. 41. 基于HTTP的监控和管理 i. 41.1. 保护敏感端点 ii. 41.2. 自定义管理服务器的上下文路径 iii. 41.3. 自定义管理服务器的端口 iv. 41.4. 自定义管理服务器的地址 v. 41.5. 禁用HTTP端点 vi. 41.6. HTTP Health端点访问限制 iv. 42. 基于JMX的监控和管理 i. 42.1. 自定义MBean名称 ii. 42.2. 禁用JMX端点 iii. 42.3. 使用Jolokia通过HTTP实现JMX远程管理 i. 42.3.1. 自定义Jolokia ii. 42.3.2. 禁用Jolokia iv. 43. 使用远程shell来进行监控和管理 i. 43.1. 连接远程shell i. 43.1.1. 远程shell证书 ii. 43.2. 扩展远程shell i. 43.2.1. 远程shell命令 ii. 43.2.2. 远程shell插件 v. 44. 度量指标(Metrics) i. 44.1. 系统指标 Spring Boot参考指南 5 ii. 44.2. 数据源指标 iii. 44.3. Tomcat session指标 iv. 44.4. 记录自己的指标 v. 44.5. 添加你自己的公共指标 vi. 44.6. 指标仓库 vii. 44.7. Dropwizard指标 viii. 44.8. 消息渠道集成 vi. 45. 审计 vii. 46. 追踪(Tracing) i. 46.1. 自定义追踪 viii. 47. 进程监控 i. 47.1. 扩展属性 ii. 47.2. 以编程方式 ix. 48. 接下来阅读什么 7. VI. 部署到云端 i. 49. Cloud Foundry i. 49.1. 绑定服务 ii. 50. Heroku iii. 51. Openshift iv. 52. Google App Engine v. 53. 接下来阅读什么 8. VII. Spring Boot CLI i. 54. 安装CLI ii. 55. 使用CLI i. 55.1. 使用CLI运行应用 i. 55.1.1. 推断"grab"依赖 ii. 55.1.2. 推断"grab"坐标 iii. 55.1.3. 默认import语句 iv. 55.1.4. 自动创建main方法 v. 55.1.5. 自定义"grab"元数据 ii. 55.2. 测试你的代码 iii. 55.3. 多源文件应用 iv. 55.4. 应用打包 v. 55.5. 初始化新工程 vi. 55.6. 使用内嵌shell vii. 55.7. 为CLI添加扩展 iii. 56. 使用Groovy beans DSL开发应用 iv. 57. 接下来阅读什么 9. VIII. 构建工具插件 i. 58. Spring Boot Maven插件 i. 58.1. 包含该插件 ii. 58.2. 打包可执行jar和war文件 ii. 59. Spring Boot Gradle插件 i. 59.1. 包含该插件 ii. 59.2. 声明不带版本的依赖 i. 59.2.1. 自定义版本管理 iii. 59.3. 默认排除规则 iv. 59.4. 打包可执行jar和war文件 v. 59.5. 就地(in-place)运行项目 vi. 59.6. Spring Boot插件配置 vii. 59.7. Repackage配置 viii. 59.8. 使用Gradle自定义配置进行Repackage i. 59.8.1. 配置选项 Spring Boot参考指南 6 ix. 59.9. 理解Gradle插件是如何工作的 iii. 60. 对其他构建系统的支持 i. 60.1. 重新打包存档 ii. 60.2. 内嵌的库 iii. 60.3. 查找main类 iv. 60.4. repackage实现示例 iv. 61. 接下来阅读什么 10. IX. How-to指南 i. 62. Spring Boot应用 i. 62.1. 解决自动配置问题 ii. 62.2. 启动前自定义Environment或ApplicationContext iii. 62.3. 构建ApplicationContext层次结构(添加父或根上下文 iv. 62.4. 创建一个非web(non-web)应用 ii. 63. 属性&配置 i. 63.1. 外部化SpringApplication配置 ii. 63.2. 改变应用程序外部配置文件的位置 iii. 63.3. 使用'short'命令行参数 iv. 63.4. 使用YAML配置外部属性 v. 63.5. 设置生效的Spring profiles vi. 63.6. 根据环境改变配置 vii. 63.7. 发现外部属性的内置选项 iii. 64. 内嵌的servlet容器 i. 64.1. 为应用添加Servlet,Filter或ServletContextListener ii. 64.2. 改变HTTP端口 iii. 64.3. 使用随机未分配的HTTP端口 iv. 64.4. 发现运行时的HTTP端口 v. 64.5. 配置SSL vi. 64.6. 配置Tomcat vii. 64.7. 启用Tomcat的多连接器(Multiple Connectors) viii. 64.8. 在前端代理服务器后使用Tomcat ix. 64.9. 使用Jetty替代Tomcat x. 64.10. 配置Jetty xi. 64.11. 使用Undertow替代Tomcat xii. 64.12. 配置Undertow xiii. 64.13. 启用Undertow的多监听器 xiv. 64.14. 使用Tomcat7 i. 64.14.1. 通过Maven使用Tomcat7 ii. 64.14.2. 通过Gradle使用Tomcat7 xv. 64.15. 使用Jetty8 i. 64.15.1. 通过Maven使用Jetty8 ii. 64.15.2. 通过Gradle使用Jetty8 xvi. 64.16. 使用@ServerEndpoint创建WebSocket端点 xvii. 64.17. 启用HTTP响应压缩 i. 64.17.1. 启用Tomcat的HTTP响应压缩 ii. 64.17.2. 使用GzipFilter开启HTTP响应压缩 iv. 65. Spring MVC i. 65.1. 编写一个JSON REST服务 ii. 65.2. 编写一个XML REST服务 iii. 65.3. 自定义Jackson ObjectMapper iv. 65.4. 自定义@ResponseBody渲染 v. 65.5. 处理Multipart文件上传 vi. 65.6. 关闭Spring MVC DispatcherServlet vii. 65.7. 关闭默认的MVC配置 Spring Boot参考指南 7 viii. 65.8. 自定义ViewResolvers v. 66. 日志 i. 66.1. 配置Logback ii. 66.2. 配置Log4j i. 66.2.1. 使用YAML或JSON配置Log4j2 vi. 67. 数据访问 i. 67.1. 配置一个数据源 ii. 67.2. 配置两个数据源 iii. 67.3. 使用Spring Data仓库 iv. 67.4. 从Spring配置分离@Entity定义 v. 67.5. 配置JPA属性 vi. 67.6. 使用自定义的EntityManagerFactory vii. 67.7. 使用两个EntityManagers viii. 67.8. 使用普通的persistence.xml ix. 67.9. 使用Spring Data JPA和Mongo仓库 x. 67.10. 将Spring Data仓库暴露为REST端点 vii. 68. 数据库初始化 i. 68.1. 使用JPA初始化数据库 ii. 68.2. 使用Hibernate初始化数据库 iii. 68.3. 使用Spring JDBC初始化数据库 iv. 68.4. 初始化Spring Batch数据库 v. 68.5. 使用一个高级别的数据迁移工具 i. 68.5.1. 启动时执行Flyway数据库迁移 ii. 68.5.2. 启动时执行Liquibase数据库迁移 viii. 69. 批处理应用 i. 69.1. 在启动时执行Spring Batch作业 ix. 70. 执行器(Actuator) i. 70.1. 改变HTTP端口或执行器端点的地址 ii. 70.2. 自定义'白标'(whitelabel,可以了解下相关理念)错误页面 x. 71. 安全 i. 71.1. 关闭Spring Boot安全配置 ii. 71.2. 改变AuthenticationManager并添加用户账号 iii. 71.3. 当前端使用代理服务器时,启用HTTPS xi. 72. 热交换 i. 72.1. 重新加载静态内容 ii. 72.2. 在不重启容器的情况下重新加载Thymeleaf模板 iii. 72.3. 在不重启容器的情况下重新加载FreeMarker模板 iv. 72.4. 在不重启容器的情况下重新加载Groovy模板 v. 72.5. 在不重启容器的情况下重新加载Velocity模板 vi. 72.6. 在不重启容器的情况下重新加载Java类 i. 72.6.1. 使用Maven配置Spring Loaded ii. 72.6.2. 使用Gradle和IntelliJ配置Spring Loaded xii. 73. 构建 i. 73.1. 使用Maven自定义依赖版本 ii. 73.2. 使用Maven创建可执行JAR iii. 73.3. 创建其他的可执行JAR iv. 73.4. 在可执行jar运行时提取特定的版本 v. 73.5. 使用排除创建不可执行的JAR vi. 73.6. 远程调试一个使用Maven启动的Spring Boot项目 vii. 73.7. 远程调试一个使用Gradle启动的Spring Boot项目 viii. 73.8. 使用Ant构建可执行存档(archive) ix. 73.9. 如何使用Java6 i. 73.9.1. 内嵌Servlet容器兼容性 Spring Boot参考指南 8 ii. 73.9.2. JTA API兼容性 xiii. 74. 传统部署 i. 74.1. 创建一个可部署的war文件 ii. 74.2. 为老的servlet容器创建一个可部署的war文件 iii. 74.3. 将现有的应用转换为Spring Boot iv. 74.4. 部署WAR到Weblogic v. 74.5. 部署WAR到老的(Servlet2.5)容器 11. X.附录 i. 附录A. 常见应用属性 ii. 附录B. 配置元数据 i. 附录B.1. 元数据格式 i. 附录B.1.1. Group属性 ii. 附录B.1.2. Property属性 iii. 附录B.1.3. 可重复的元数据节点 ii. 附录B.2. 使用注解处理器产生自己的元数据 i. 附录 B.2.1. 内嵌属性 ii. 附录 B.2.2. 添加其他的元数据 iii. 附录C. 自动配置类 i. 附录 C.1. 来自spring-boot-autoconfigure模块 ii. 附录C.2. 来自spring-boot-actuator模块 iv. 附录D. 可执行jar格式 i. 附录D.1. 内嵌JARs i. 附录D.1.1. 可执行jar文件结构 ii. 附录D.1.2. 可执行war文件结构 ii. 附录D.2. Spring Boot的"JarFile"类 i. 附录D.2.1. 对标准Java "JarFile"的兼容性 iii. 附录D.3. 启动可执行jars i. 附录D.3.1 Launcher manifest ii. 附录D.3.2. 暴露的存档 iv. 附录D.4. PropertiesLauncher特性 v. 附录D.5. 可执行jar的限制 i. 附录D.5.1. Zip实体压缩 ii. 附录D.5.2. 系统ClassLoader vi. 附录D.6. 可替代的单一jar解决方案

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值