出版社: 人民邮电出版社
原作名: Spring in Action,Fourth Edition
译者: 张卫滨
出版年: 2016-4-1
页数: 577
定价: CNY 89.00
装帧: 平装
ISBN: 9787115417305
内容简介 · · · · · ·
《Spring实战(第4版)》是经典的、畅销的Spring学习和实践指南。
第4版针对Spring 4进行了全面更新。全书分为四部分。第1部分介绍Spring框架的核心知识。第二部分在此基础上介绍了如何使用Spring构建Web应用程序。第三部分告别前端,介绍了如何在应用程序的后端使用Spring。第四部分描述了如何使用Spring与其他的应用和服务进行集成。
《Spring实战(第4版)》适用于已具有一定Java 编程基础的读者,以及在Java 平台下进行各类软件开发的开发人员、测试人员,尤其适用于企业级Java 开发人员。本书既可以被刚开始学习Spring 的读者当作学习指南,也可以被那些想深入了解Spring 某方面功能的专业用户作为参考用书。
作者简介 · · · · · ·
Craig Walls是Pivotal的高级工程师,是Spring Social和Spring Sync的项目领导者,同时也是Manning出版社《Spring In Action》的作者,目前这本书已经更新到了第四版。他非常热心于Spring框架的推广,经常在当地的用户组和会议上演讲并在博客上撰写Spring相关的内容。在不琢磨代码的时候,Craig Walls会尽可能多地陪伴他的妻子、两个女儿、两只小鸟以及两只小狗。
目录 · · · · · ·
第1章 Spring之旅 3
1.1 简化Java开发 4
1.1.1 激发POJO的潜能 5
1.1.2 依赖注入 5
1.1.3 应用切面 11
· · · · · · (更多)
第1章 Spring之旅 3
1.1 简化Java开发 4
1.1.1 激发POJO的潜能 5
1.1.2 依赖注入 5
1.1.3 应用切面 11
1.1.4 使用模板消除样板式代码 16
1.2 容纳你的Bean 18
1.2.1 使用应用上下文 19
1.2.2 bean的生命周期 20
1.3 俯瞰Spring风景线 21
1.3.1 Spring模块 22
1.3.2 Spring Portfolio 24
1.4 Spring的新功能 27
1.4.1 Spring 3.1新特性 27
1.4.2 Spring 3.2新特性 28
1.4.3 Spring 4.0新特性 30
1.5 小结 30
第2章 装配Bean 33
2.1 Spring配置的可选方案 34
2.2 自动化装配bean 35
2.2.1 创建可被发现的bean 35
2.2.2 为组件扫描的bean命名 38
2.2.3 设置组件扫描的基础包 39
2.2.4 通过为bean添加注解实现自动装配 40
2.2.5 验证自动装配 42
2.3 通过Java代码装配
bean 44
2.3.1 创建配置类 44
2.3.2 声明简单的bean 45
2.3.3 借助JavaConfig实现注入 46
2.4 通过XML装配bean 48
2.4.1 创建XML配置规范 48
2.4.2 声明一个简单的
[bean] 49
2.4.3 借助构造器注入初始化bean 50
2.4.4 设置属性 56
2.5 导入和混合配置 61
2.5.1 在JavaConfig中引用XML配置 61
2.5.2 在XML配置中引用JavaConfig 63
2.6 小结 65
第3章 高级装配 67
3.1 环境与profile 67
3.1.1 配置profile bean 69
3.1.2 激活profile 73
3.2 条件化的bean 75
3.3 处理自动装配的歧义性 78
3.3.1 标示首选的bean 79
3.3.2 限定自动装配的bean 80
3.4 bean的作用域 84
3.4.1 使用会话和请求作用域 86
3.4.2 在XML中声明作用域代理 88
3.5 运行时值注入 88
3.5.1 注入外部的值 89
3.5.2 使用Spring表达式语言进行装配 93
3.6 小结 99
第4章 面向切面的Spring 101
4.1 什么是面向切面编程? 102
4.1.1 定义AOP术语 103
4.1.2 Spring对AOP的支持 105
4.2 通过切点来选择连接点 107
4.2.1 编写切点 108
4.2.2 在切点中选择bean 109
4.3 使用注解创建切面 109
4.3.1 定义切面 110
4.3.2 创建环绕通知 114
4.3.3 处理通知中的参数 115
4.3.4 通过注解引入新功能 118
4.4 在XML中声明切面 120
4.4.1 声明前置和后置通知 122
4.4.2 声明环绕通知 124
4.4.3 为通知传递参数 125
4.4.4 通过切面引入新的功能 127
4.5 注入AspectJ切面 128
4.5 小结 131
第2部分 Web中的Spring
第5章 构建Spring Web应用程序 135
5.1 Spring MVC起步 136
5.1.1 跟踪Spring MVC的请求 136
5.1.2 搭建Spring MVC 138
5.1.3 Spittr应用简介 142
5.2 编写基本的控制器 143
5.2.1 测试控制器 145
5.2.2 定义类级别的请求处理 146
5.2.3 传递模型数据到视图中 147
5.3 接受请求的输入 153
5.3.1 处理查询参数 153
5.3.2 通过路径参数接受输入 155
5.4 处理表单 157
5.4.1 编写处理表单的控制器 160
5.4.2 校验表单 163
5.5 小结 166
第6章 渲染Web视图 167
6.1 理解视图解析 167
6.2 创建JSP视图 170
6.2.1 配置适用于JSP的视图解析器 170
6.2.2 使用Spring的JSP库 172
6.3 使用Apache Tiles视图定义布局 184
6.3.1 配置Tiles视图解析器 185
6.4 使用Thymeleaf 190
6.4.1 配置Thymeleaf视图解析器 190
6.4.2 定义Thymeleaf模板 192
6.5 小结 196
第7章 Spring MVC的高级技术 197
7.1 Spring MVC配置的替代方案 198
7.1.1 自定义DispatcherServlet配置 198
7.1.2 添加其他的Servlet和Filter 199
7.1.3 在web.xml中声明DispatcherServlet 201
7.2 处理multipart形式的数据 204
7.2.1 配置multipart解析器 205
7.2.2 处理multipart请求 208
7.3 处理异常 212
7.3.1 将异常映射为HTTP状态码 213
7.3.2 编写异常处理的方法 214
7.4 为控制器添加通知 216
7.5 跨重定向请求传递数据 217
7.5.1 通过URL模板进行重定向 218
7.5.2 使用flash属性 219
7.6 小结 221
第8章 使用Spring WebFlow 223
8.1 在Spring中配置Web Flow 224
8.1.1 装配流程执行器 224
8.1.2 配置流程注册表 224
8.1.3 处理流程请求 225
8.2 流程的组件 226
8.2.1 状态 226
8.2.2 转移 230
8.2.3 流程数据 231
8.3 组合起来:披萨流程 232
8.3.1 定义基本流程 233
8.3.2 收集顾客信息 236
8.3.2 构建订单 242
8.3.2 支付 244
8.4 保护Web流程 246
8.5 小结 246
第9章 保护Web应用 249
9.1 Spring Security简介 250
9.1.1 理解Spring Security的模块 250
9.1.2 过滤Web请求 251
9.1.3 编写简单的安全性配置 252
9.2 选择查询用户详细信息的服务 255
9.2.1使用基于内存的用户存储 255
9.2.2 基于数据库表进行认证 257
9.2.3 基于LDAP进行认证 259
9.2.4 配置自定义的用户服务 263
9.3 拦截请求 265
9.3.1 使用Spring表达式进行安全保护 267
9.3.2 强制通道的安全性 269
9.3.3 防止跨站请求伪造 270
9.4 认证用户 271
9.4.1 添加自定义的登录页 272
9.4.2 启用HTTP Basic认证 274
9.4.3 启用Remember-me功能 274
9.4.4 退出 275
9.5 保护视图 276
9.5.1 使用Spring Security的JSP标签库 276
9.5.2 使用Thymeleaf的SpringSecurity方言 280
9.6 小结 281
第3部分 后端中的Spring
第10章 通过Spring和JDBC征服数据库 285
10.1 Spring的数据访问哲学 286
10.1.1 了解Spring的数据访问异常体系 287
10.1.2 数据访问模板化 289
10.2 配置数据源 291
10.2.1 使用JNDI数据源 292
10.2.2 使用数据源连接池 292
10.2.3 基于JDBC驱动的数据源 294
10.2.4 使用嵌入式的数据源 295
10.2.5 使用profile选择数据源 296
10.3 在Spring中使用
JDBC 298
10.3.1 应对失控的JDBC代码 299
10.3.2 使用JDBC模板 302
10.4 小结 307
第11章 使用对象-关系映射持久化数据 309
11.1 在Spring中集成Hibernate 310
11.1.1 声明Hibernate的Session工厂 311
11.1.2 构建不依赖于Spring的Hibernate代码 313
11.2 Spring与Java持久化API 315
11.2.1 配置实体管理器工厂 315
11.2.2 编写基于JPA的Repository 320
11.3 借助Spring Data实现自动化的JPA Repository 322
11.3.1 定义查询方法 325
11.3.2 声明自定义查询 328
11.3.3 混合自定义的功能 329
11.4 小结 330
第12章 使用NoSQL数据库 333
12.1 使用MongoDB持久化文档数据 334
12.1.1 启用MongoDB 335
12.1.2 为模型添加注解,实现MongoDB持久化 338
12.1.3 使用MongoTemplate访问MongoDB 341
12.1.4 编写MongoDBRepository 342
12.2 使用Neo4j操作图数据 347
12.2.1 配置Spring DataNeo4j 347
12.2.2 使用注解标注图实体 350
12.2.3 使用Neo4jTemplate 353
12.2.4 创建自动化的Neo4j Repository 354
12.3 使用Redis操作key-value数据 359
12.3.1 连接到Redis 359
12.3.2 使用RedisTemplate 360
12.3.3 使用key和value的序列化器 364
12.4 小结 365
第13章 缓存数据 367
13.1 启用对缓存的支持 368
13.1.1 配置缓存管理器 369
13.2 为方法添加注解以支持缓存 373
13.2.1 填充缓存 374
13.2.2 移除缓存条目 378
13.3 使用XML声明缓存 379
13.4 小结 383
第14章 保护方法应用 385
14.1 使用注解保护方法 386
14.1.1 使用@Secured注解限制方法调用 386
14.1.2 在Spring Security中使用
JSR-250的@RolesAllowed注解 387
14.2 使用表达式实现方法级别的安全性 388
14.2.1 表述方法访问规则 389
14.2.2 过滤方法的输入和输出 391
14.3 小结 395
第4部分 Spring集成
第15章 使用远程服务 399
15.1 Spring远程调用概览 400
15.2 使用RMI 402
15.2.1 导出RMI服务 403
15.2.2 装配RMI服务 405
15.3 使用Hessian和Burlap发布远程服务 407
15.3.1 使用Hessian和Burlap导出bean的功能 408
15.3.2 访问Hessian/Burlap服务 411
15.4 使用Spring的HttpInvoker 413
15.4.1 将bean导出为HTTP服务 413
15.4.2 通过HTTP访问服务 414
15.5 发布和使用Web服务 416
15.5.1 创建基于Spring的JAX-WS端点 416
15.5.2 在客户端代理JAX-WS服务 419
15.6 小结 421
第16章 使用Spring MVC创建REST API 423
16.1 了解REST 424
16.1.1 REST的基础知识 424
16.1.2 Spring是如何支持REST的 425
16.2 创建第一个REST端点 426
16.2.1 协商资源表述 428
16.2.2 使用HTTP信息转换器 433
16.3 提供资源之外的其他内容 438
16.3.1 发送错误信息到客户端 438
16.3.2 在响应中设置头部信息 443
16.4 编写REST客户端 445
16.4.1 了解RestTemplate的操作 446
16.4.2 GET资源 447
16.4.3 检索资源 448
16.4.4 抽取响应的元数据 449
16.4.5 PUT资源 450
16.4.6 DELETE资源 451
16.4.7 POST资源数据 452
16.4.8 在POST请求中获取响应对象 452
16.4.9 在POST请求后获取资源位置 453
16.4.10 交换资源 454
16.5 小结 456
第17章 Spring消息 457
17.1 异步消息简介 458
17.1.1 发送消息 459
17.1.2 评估异步消息的优点 461
17.2 使用JMS发送消息 463
17.2.1 在Spring中搭建消息代理 463
17.2.2 使用Spring的JMS模板 465
17.2.3 创建消息驱动的POJO 474
17.2.4 使用基于消息的RPC 477
17.3 使用AMQP实现消息功能 479
17.3.1 AMQP简介 480
17.3.2 配置Spring支持AMQP消息 481
17.3.3 使用RabbitTemplate发送消息 484
17.3.4 接收AMQP消息 486
17.4 小结 489
第18章 使用WebSocket和STOMP实现消息功能 491
18.1 使用Spring的低层级WebSocket API 492
18.2 应对不支持WebSocket的场景 497
18.3 使用STOMP消息 500
18.3.1 启用STOMP消息功能 501
18.3.2 处理来自客户端的STOMP消息 504
18.3.3 发送消息到客户端 507
18.4 为目标用户发送消息 511
18.4.1 在控制器中处理用户的消息 512
18.4.2 为指定用户发送消息 514
18.5 处理消息异常 515
18.6 小结 516
第19章 使用Spring发送Email 517
19.1 配置Spring发送邮件 518
19.1.1 配置邮件发送器 518
19.1.2 装配和使用邮件发送器 520
19.2 构建丰富内容的Email消息 521
19.2.1 添加附件 521
19.2.2 发送富文本内容的Email 522
19.3 使用模板生成Email 524
19.3.1 使用Velocity构建Email消息 524
19.3.2 使用Thymeleaf构建Email消息 526
19.4 小结 528
第20章 使用JMX管理Spring Bean 529
20.1 将Spring bean导出为MBean 530
20.1.1 通过名称暴露方法 533
20.1.2 使用接口定义MBean的操作和属性 535
20.1.3 使用注解驱动的MBean 536
20.1.4 处理MBean冲突 538
20.2 远程MBean 539
20.2.1 暴露远程MBean 539
20.2.2 访问远程MBean 540
20.2.3 代理MBean 542
20.3 处理通知 543
20.3.1 监听通知 544
20.4 小结 545
第21章 借助Spring Boot简化Spring开发 547
21.1 Spring Boot简介 548
21.1.1 添加Starter依赖 548
21.1.2 自动配置 552
21.1.3 Spring Boot CLI 552
21.1.4 Actuator 553
21.2 使用Spring Boot构建应用 553
21.2.1 处理请求 556
21.2.2 创建视图 558
21.2.3 添加静态内容 560
21.2.4 持久化数据 561
21.2.5 尝试运行 563
21.3 组合使用Groovy与SpringBoot CLI 566
21.3.1 编写Groovy控制器 566
21.3.2 使用Groovy Repository实现数据持久化 569
21.3.3 运行Spring Boot CLI 570
21.4 通过Actuator获取了解应用内部状况 571
21.5 小结 574
· · · · · · (收起)
喜欢读"Spring实战(第4版)"的人也喜欢的电子书 · · · · · ·
喜欢读"Spring实战(第4版)"的人也喜欢 · · · · · ·
Spring实战(第4版)的话题 · · · · · · ( 全部 条 )



Spring实战(第4版)的书评 · · · · · · ( 全部 36 条 )


Spring很好的入门书籍

翻译差点可以忍 出版社编辑太垃圾了

总的来说不错,质量方面比较雷

把一本好书给翻烂了!

一本不错的关于Spring的书籍

关于Spring的新华字典
> 更多书评 36篇
-
读这本书的动机 为了更全面深入了解一门技术。作为技术技术从业者,凡事探其究竟。Spring是一个在互联网从业者 广泛应用的开发框架,已经流行多年。而且凡编程都会提到这一框架。然而对其却很少深入。简单的 说一个框架知道如何用便可以应付工作中的需要。可要追本溯源,便要了解其发展。这里说大部分是 我个人理解,以及查阅资料总结所得。在最初使用spring只知道它是一个强大的web开发框架,然而 对它的强大之处却并不体会,...
2020-08-11 22:30:53
读这本书的动机
为了更全面深入了解一门技术。作为技术技术从业者,凡事探其究竟。Spring是一个在互联网从业者
广泛应用的开发框架,已经流行多年。而且凡编程都会提到这一框架。然而对其却很少深入。简单的
说一个框架知道如何用便可以应付工作中的需要。可要追本溯源,便要了解其发展。这里说大部分是
我个人理解,以及查阅资料总结所得。在最初使用spring只知道它是一个强大的web开发框架,然而
对它的强大之处却并不体会,这种强大大部分是对比EJB(即Java标准发布者发布的企业级框架)以
及当今web开发常用框架来说的。而这些主要体现在易用上。在软件的发展过程中有很多的框架,EJB
作为Java的官方发布显得更有权威一些,然而事实上却令很多开发人员抱怨其开发过于笨重,事实上
很多的开发实际上不用如此重量级的框架。简单说一半我们都需要盖一个二层小楼,而EJB提供的设备
却是盖摩天大楼用的,放在一个普通的应用身上,这不仅显得大材小用,而实际上EJB在开发上通常要
按照它的框架来盖楼,必须要遵守它的规范。然而spring正是在这一点上体现了它的超越之处,它在
开发过程中解脱了对开发者的这种束缚,当然这对于大多数应用来说,在最初,spring显然是超越了
EJB,被广泛采用;虽然spring不像EJB那种企业级标准来说能够全面覆盖到所有的面,但spring
优秀的设计思想已被接纳并经过验证;随着spring的广泛支持,它也逐渐被Java标准所吸纳,而后来
的EJB版本也引入了sping。所以Spring于EJB可能在本质上区别之处并不大,在不同时期它们或许都有
特定的意义。但spring这一框架思想被广泛认可而被逐渐接受,逐渐走向标准化;这一过程中也有许
多其它的框架产生,在这过程中spring被逐渐筛选而逐渐成为主流。
关于这本书的收获:
Spring是优秀的设计框架,我的理解这主要是得益于它的设计思想,它最初的设计是为了使应用框架
更简单和轻松(尽管优秀的框架也并不完全能达到这一点,但spring得确非常优秀),相比EJB框架
来说它的简单之处就在于不用像EJB那样,在其框架上建房子,要使用一堆臃肿甚至看似无用的代码,
来满足EJB标准的要求。在spring当中只需要简单得代码注明即可,甚至看不到痕迹。因为这一切都由
spring框架管理了起来,像EJB那样,能完成同样的功能,却能如此的优雅,我想这也是spring
设计初衷 -- “最小侵入式编程”的体现。Spring轻简的使用方式得益于依赖注入的设计,在另一方面
spring面向切面这一功能使得更多的需要可以切入到代码当中完成其它的需要,这样解决了代码复用
的问题,例如安全事务,日志等。
关于这本书得整体概括,可以说spring最核心的技术在于依赖注入(Dependency Injection)
和面向切面编程(Aspect Oriented Programming),从技术角度来看,依赖注入解决了开发过程中
耦合的问题,它通过简单的注解或配置的方式,把这种依赖交由框架管理起来,而且这种方式非常
方便易用,使得代码显得更加清晰易懂,也便于以后的管理。而在横向上,spring借鉴了面向切面这一
概念使代码功能模块实现分离,从而达到重用。这也是我认为读本书最核心要了解的知识,其中关于
这部分的讲解占据前一部分,后一部分是在各个方向的应用,如数据库,事务管理,以及在工程项目
当中的应用。
Spring实战这本书涵盖了Spring框架核的心思想,即是Dependcy Injection (DI)依赖注入,和Aspect Oriented Programming(AOP)面向切面编程;同时这本书也在其核心思想基础上向各个方向展开,数据库,事务管理等等。往往经典的框架都是简单易用的。Spring或许应了这句话,当初也正是因为Sun公司发布的EJB框架没能满足这样需求,在实际应用中显得臃肿而复杂。这也便是spring成为流行趋势的原因。对比EJB,它要求使用者必须继承它的框架,遵从它的规范来进行开发,在一个企业级应用开发中,开发人员所期望创建的流程必须在EJB所规定的框架之下;然而spring打破了这样的束缚,它让开发自由度更大,释放了这种规范的要求,这在思想上就高了一筹;而且spring避免了EJB代码开发中高度的耦合与复杂的场景这也得益于spring框架DJ和AOP的好处,让java开发变得简单这一趋势所产生的。
回应 2020-08-11 22:30:53 -
Spring核心 “我的建议是尽可能地使用自动配置的机制。显式配置越少越好。当你必须要显式配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),我推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML”。 自动化装配bean Spring从两个角度实现自动化配置 组件扫描(component scanning) 自动装配(...
2018-11-28 20:11:36
Spring核心
“我的建议是尽可能地使用自动配置的机制。显式配置越少越好。当你必须要显式配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),我推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML”。 引自 Spring in action 自动化装配bean
Spring从两个角度实现自动化配置
组件扫描(component scanning) 自动装配(autowiring) 引自 Spring in action @Component注解
表明该类会作为组件,并告知Spring要为这个类创建bean,不需要显示配置bean。
为bean命名:@Component("Name")
@ComponentScan注解
组件扫描默认是不启用的,需要使用该注解用以下方式启用:在配置类上标注即可。 默认情况下只扫描当前包及其子包。也可以设置组件扫描的基础包:
@ComponentScan("Name") @ComponentScan(basePackages="Name") @ComponentScan(basePackages={"Name1", "Name2", ...}) @ComponentScan(basePackageClasses={Name1.class, Name2.class}) 引自 Spring in action @Autowrited注解
自动装配,可以使用在构造器,方法,属性之上以获得自动装配。当没有匹配的组件时,会抛出异常。设置required属性为false可以避免抛出,但要十分谨慎检查对象是否为null。如果多个对象可以匹配,同样抛出异常。
@Named、@Inject注解
与 @Component注解、@Autowrited注解有细微差别大多情况下可以替换使用,来源于Java依赖注入规范(Java Dependency Injection)。
@ContextConfiguration注解
@ContextConfiguration(classes=*.class)用于标记加载配置类位置。 @ContextConfiguration({"classpath:*.xml"})用于标记加载配置xml文件位置。
@RunWirh
运行器
基于Java的配置
@Bean
声明bean。产生单例对象。唯一限制java方式配置的是java语言特性。
基于XML的配置
构造器注入 <cnstructor-arg>
id表示标;class类名;注入单值时使用value属性;应用其他bean时使用ref属性。 使用命名空间c装配,声明c的URI后可以使用 c: 构造器参数名[-ref]="value" 形式装配。也可以使用参数顺序编号代替参数名,c: _index[-ref]="value" ,当只有一个参数时可以省略编号。
属性注入 <property>
id表示标;class类名;注入单值时使用value属性;应用其他bean时使用ref属性。 使用命名空间p装配,声明c的URI后可以使用 p: 构造器参数名[-ref]="value" 形式装配。也可以使用参数顺序编号代替参数名,p: _index[-ref]="value" ,当只有一个参数时可以省略编号。
装配集合
<list> <set> <map> <props> 引自 Spring in action <list><value>value</value></list>
然而c或者p命名空间并不能装配集合,使用util命名空间:
<uilt:list> <uilt:set> <uilt:map> <uilt:props> 引自 Spring in action <util:list id="name"><value>value</value></util:list>
之后使用id属性引用它。
导入和混合配置
@Import @ImportResource 标签
在java配置中使用
@Import({*.class, ...})
导入其他配置类,使用@ImportResource("*.xml")
导入xml配置。<import>标签
在xml配置中使用
<import>
标签导入其他xml配置,使用<bean>
标签导入java配置类。profile
有选择的配置bean
在java配置类中配置
在类上使用
@profile("name")
配置,只有在"name" profile激活时词才会创建。在方法上使用时,可以在一个配置类中声明不同的profile。没有声明的bean无论激活哪个profile都会创建。在xml中配置
在
<beans>
标签中配置profile
属性。激活profile
设置
spring.proflies.active
和spring.profiles.default
。如果设置active,就按active;未设置active,则按default;均未设置,没有激活的profile。激活的方式有很多,目前还不是太了解那些条目是什么意思。只知道在测试类上可以使用@ActiveProfiles("name")
设置。条件化bean
@Conditional标签
@Conditional(*.class)
标记bean,类实现Condition接口,实现接口中的matches方法,返回一个boolean,ture创建bean。 Condition接口:public interface Condition { boolean matches (ConditionContext ctxt, AnnotatedTypeMetadata metadata); }
自动装配的歧义
@Primary标签
标记首选bean,在xml配置中使用bean的primary属性设为true。
@Qualifier标签
可以与
@Autowrited
和@Inject
协同使用,指定要注入的是哪个bean。限定符与bean的ID相同,这样当重构bean时ID可能有变化,自动装配可能会失败,自定义限定符。声明bean时候与@Component
组合使用,@Qualifier("name")
。自定义限定符注解
一个java类,形式如下:
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementTypt.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface Name {}
通过使用多个
@Name
标签限定bean装配。Bean作用域
默认情况下是单例(Singleton)的。还包括原型(Prototype)、会话(Session)、请求(Request)。
@Scope标签
使用
@Scope("name")
设置。可以是字符串,但是使用ConfigurableBeanFactory
更不容易出错。如果使用xml配置使用bean的scope属性。会话和请求作用域
预留
属性占位符(Property placeholder)
@PropertySource("path")
声明属性源,从属性源中获取值,使用Environment的getProperty()方法。getProperty()有重载方法,用于类型转换。getRequiredProperty()属性不存在是抛出异常的getProperty()版本。 还有String[] getDefaultProfiles()和String[] getActiveProfiles()获取那些profile处于激活的状态。占位符${...}
为了使用占位符需要配置一个类:
@Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); }
如果使用xml:
<context:property-placeholder />
在xml中直接使用。在自动扫描和java配置中,用
@Value("&{...}")
标签,在属性前使用。SpEl
表达式形式如
#{...}
。很灵活。使用 T()
引用java类,之后通过.访问静态方法、静态属性 使用beanID引用bean,调用方法,属性 使用systemProperties
引用系统属性 在xml和@Value
中组合使用 调用方法时在.
之前使用?
,如果是null
值则不调用该方法 使用运算符和正则表达式(字符串matches
表达式) 使用[index]
引用集合元素,获取字符串字符.?[表达式]
,返回集合中表达式为真的子集.^[]
和.$[]
,查询第一个和最后一个匹配项.![属性]
,选择属性到新集合中引自 Spring in action 后四个对于集合使用。组合起来非常灵活。
Spring AOP
Spring只支持方法级别的连接点。切面要声明为一个bean。
通知
五种类型
前置通知before 后置通知after 返回通知after-return 异常通知after-throwing 环绕通知around 引自 Spring in action 连接点
可以插入通知的位置
切点
插入通知的位置
切面(Aspect)
通知和写点共同定义了切面
引入(Introduction)
向现有类添加新方法
织入(Weaving)
把切面应用到目标对象并创建新的代理对象的过程,多个点可以织入:
编译期,AspectJ织入方式 类加载期,需要特殊的类加载器,AspectJ5的加载时织入支持 运行期,SpringAOP织入方式 引自 Spring in action 编写切点
execution(返回值类型 方法所属类.方法(参数类型)) [操作符 指示器]
返回任意类型时使用*
,使用任意参数时使用(..)
,可选的操作符指示器,例如指示器arg等。bean指示器用于选择特定id的bean。使用注解创建切面
使用@Aspect标记切面。@Before @After @AfterReturing @AfterThrowing注解,使用
注解(切点)
的方式在方法上使用。使用方法名称引用切点:
@Pointcut(切点) 方法名称() {}
@EnableAspectJAutoProxy注解
在JavaConfig中启用自动代理,xml中使用
<aop:aspectj-autoproxy>
环绕通知
@Around注解注释环绕通知,被环绕的方法必要的
ProceedingJoinPoint
类型参数。并调用proceed()
方法执行被通知方法。处理参数
execution(返回值类型 方法所属类.方法(参数类型)) [操作符 指示器]
使用
args(参数名称)
指示器,在注解中加入参数名称,参数名称要与切点方法签名中的方法名称匹配。通过直接引入新功能
@DelcareParents(value="bean类型", defaultImpl=实现类.class) public static 功能接口
在xml中声明切面
<aop:config>
从它开始。<aop:aspect ref="bean">
定义切面,ref提供方法。<aop:before|after|after-returning|after-throwing pointcut="切点" method="方法">
通知。<aop:pointcut id="name" expression="切点">
定义切点。<aop:around>
环绕通知。传递参数时候,在xml文件中使用and
等代替&&
。<aop:declare-parents types-matching="bean类型" implement-interface="功能接口" default-impl="实现类"|delegate-ref="bean">
引自 Spring in action 注入AspectJ切面
注意: 使用idea,需要在设置中添加“Settings->Build->Compiler->Java Compiler->Use compiler”选择Ajc,并在下面path中选择aspectjtools。
一个aspect类,*.aj文件。其中使用pointcut定义切点,before()、after()、returning()定义通知。最要是的是它可以被注入,和正常的bean一样使用。但声明bean时,要加入
factory-method
属性,值为aspectOf
。Spring不能实例化aspect,由AspectJ提供静态方法aspectOf()实例化一个单例。回应 2018-11-28 20:11:36
-
Spring核心 “我的建议是尽可能地使用自动配置的机制。显式配置越少越好。当你必须要显式配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),我推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML”。 自动化装配bean Spring从两个角度实现自动化配置 组件扫描(component scanning) 自动装配(...
2018-11-28 20:11:36
Spring核心
“我的建议是尽可能地使用自动配置的机制。显式配置越少越好。当你必须要显式配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),我推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML”。 引自 Spring in action 自动化装配bean
Spring从两个角度实现自动化配置
组件扫描(component scanning) 自动装配(autowiring) 引自 Spring in action @Component注解
表明该类会作为组件,并告知Spring要为这个类创建bean,不需要显示配置bean。
为bean命名:@Component("Name")
@ComponentScan注解
组件扫描默认是不启用的,需要使用该注解用以下方式启用:在配置类上标注即可。 默认情况下只扫描当前包及其子包。也可以设置组件扫描的基础包:
@ComponentScan("Name") @ComponentScan(basePackages="Name") @ComponentScan(basePackages={"Name1", "Name2", ...}) @ComponentScan(basePackageClasses={Name1.class, Name2.class}) 引自 Spring in action @Autowrited注解
自动装配,可以使用在构造器,方法,属性之上以获得自动装配。当没有匹配的组件时,会抛出异常。设置required属性为false可以避免抛出,但要十分谨慎检查对象是否为null。如果多个对象可以匹配,同样抛出异常。
@Named、@Inject注解
与 @Component注解、@Autowrited注解有细微差别大多情况下可以替换使用,来源于Java依赖注入规范(Java Dependency Injection)。
@ContextConfiguration注解
@ContextConfiguration(classes=*.class)用于标记加载配置类位置。 @ContextConfiguration({"classpath:*.xml"})用于标记加载配置xml文件位置。
@RunWirh
运行器
基于Java的配置
@Bean
声明bean。产生单例对象。唯一限制java方式配置的是java语言特性。
基于XML的配置
构造器注入 <cnstructor-arg>
id表示标;class类名;注入单值时使用value属性;应用其他bean时使用ref属性。 使用命名空间c装配,声明c的URI后可以使用 c: 构造器参数名[-ref]="value" 形式装配。也可以使用参数顺序编号代替参数名,c: _index[-ref]="value" ,当只有一个参数时可以省略编号。
属性注入 <property>
id表示标;class类名;注入单值时使用value属性;应用其他bean时使用ref属性。 使用命名空间p装配,声明c的URI后可以使用 p: 构造器参数名[-ref]="value" 形式装配。也可以使用参数顺序编号代替参数名,p: _index[-ref]="value" ,当只有一个参数时可以省略编号。
装配集合
<list> <set> <map> <props> 引自 Spring in action <list><value>value</value></list>
然而c或者p命名空间并不能装配集合,使用util命名空间:
<uilt:list> <uilt:set> <uilt:map> <uilt:props> 引自 Spring in action <util:list id="name"><value>value</value></util:list>
之后使用id属性引用它。
导入和混合配置
@Import @ImportResource 标签
在java配置中使用
@Import({*.class, ...})
导入其他配置类,使用@ImportResource("*.xml")
导入xml配置。<import>标签
在xml配置中使用
<import>
标签导入其他xml配置,使用<bean>
标签导入java配置类。profile
有选择的配置bean
在java配置类中配置
在类上使用
@profile("name")
配置,只有在"name" profile激活时词才会创建。在方法上使用时,可以在一个配置类中声明不同的profile。没有声明的bean无论激活哪个profile都会创建。在xml中配置
在
<beans>
标签中配置profile
属性。激活profile
设置
spring.proflies.active
和spring.profiles.default
。如果设置active,就按active;未设置active,则按default;均未设置,没有激活的profile。激活的方式有很多,目前还不是太了解那些条目是什么意思。只知道在测试类上可以使用@ActiveProfiles("name")
设置。条件化bean
@Conditional标签
@Conditional(*.class)
标记bean,类实现Condition接口,实现接口中的matches方法,返回一个boolean,ture创建bean。 Condition接口:public interface Condition { boolean matches (ConditionContext ctxt, AnnotatedTypeMetadata metadata); }
自动装配的歧义
@Primary标签
标记首选bean,在xml配置中使用bean的primary属性设为true。
@Qualifier标签
可以与
@Autowrited
和@Inject
协同使用,指定要注入的是哪个bean。限定符与bean的ID相同,这样当重构bean时ID可能有变化,自动装配可能会失败,自定义限定符。声明bean时候与@Component
组合使用,@Qualifier("name")
。自定义限定符注解
一个java类,形式如下:
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementTypt.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface Name {}
通过使用多个
@Name
标签限定bean装配。Bean作用域
默认情况下是单例(Singleton)的。还包括原型(Prototype)、会话(Session)、请求(Request)。
@Scope标签
使用
@Scope("name")
设置。可以是字符串,但是使用ConfigurableBeanFactory
更不容易出错。如果使用xml配置使用bean的scope属性。会话和请求作用域
预留
属性占位符(Property placeholder)
@PropertySource("path")
声明属性源,从属性源中获取值,使用Environment的getProperty()方法。getProperty()有重载方法,用于类型转换。getRequiredProperty()属性不存在是抛出异常的getProperty()版本。 还有String[] getDefaultProfiles()和String[] getActiveProfiles()获取那些profile处于激活的状态。占位符${...}
为了使用占位符需要配置一个类:
@Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); }
如果使用xml:
<context:property-placeholder />
在xml中直接使用。在自动扫描和java配置中,用
@Value("&{...}")
标签,在属性前使用。SpEl
表达式形式如
#{...}
。很灵活。使用 T()
引用java类,之后通过.访问静态方法、静态属性 使用beanID引用bean,调用方法,属性 使用systemProperties
引用系统属性 在xml和@Value
中组合使用 调用方法时在.
之前使用?
,如果是null
值则不调用该方法 使用运算符和正则表达式(字符串matches
表达式) 使用[index]
引用集合元素,获取字符串字符.?[表达式]
,返回集合中表达式为真的子集.^[]
和.$[]
,查询第一个和最后一个匹配项.![属性]
,选择属性到新集合中引自 Spring in action 后四个对于集合使用。组合起来非常灵活。
Spring AOP
Spring只支持方法级别的连接点。切面要声明为一个bean。
通知
五种类型
前置通知before 后置通知after 返回通知after-return 异常通知after-throwing 环绕通知around 引自 Spring in action 连接点
可以插入通知的位置
切点
插入通知的位置
切面(Aspect)
通知和写点共同定义了切面
引入(Introduction)
向现有类添加新方法
织入(Weaving)
把切面应用到目标对象并创建新的代理对象的过程,多个点可以织入:
编译期,AspectJ织入方式 类加载期,需要特殊的类加载器,AspectJ5的加载时织入支持 运行期,SpringAOP织入方式 引自 Spring in action 编写切点
execution(返回值类型 方法所属类.方法(参数类型)) [操作符 指示器]
返回任意类型时使用*
,使用任意参数时使用(..)
,可选的操作符指示器,例如指示器arg等。bean指示器用于选择特定id的bean。使用注解创建切面
使用@Aspect标记切面。@Before @After @AfterReturing @AfterThrowing注解,使用
注解(切点)
的方式在方法上使用。使用方法名称引用切点:
@Pointcut(切点) 方法名称() {}
@EnableAspectJAutoProxy注解
在JavaConfig中启用自动代理,xml中使用
<aop:aspectj-autoproxy>
环绕通知
@Around注解注释环绕通知,被环绕的方法必要的
ProceedingJoinPoint
类型参数。并调用proceed()
方法执行被通知方法。处理参数
execution(返回值类型 方法所属类.方法(参数类型)) [操作符 指示器]
使用
args(参数名称)
指示器,在注解中加入参数名称,参数名称要与切点方法签名中的方法名称匹配。通过直接引入新功能
@DelcareParents(value="bean类型", defaultImpl=实现类.class) public static 功能接口
在xml中声明切面
<aop:config>
从它开始。<aop:aspect ref="bean">
定义切面,ref提供方法。<aop:before|after|after-returning|after-throwing pointcut="切点" method="方法">
通知。<aop:pointcut id="name" expression="切点">
定义切点。<aop:around>
环绕通知。传递参数时候,在xml文件中使用and
等代替&&
。<aop:declare-parents types-matching="bean类型" implement-interface="功能接口" default-impl="实现类"|delegate-ref="bean">
引自 Spring in action 注入AspectJ切面
注意: 使用idea,需要在设置中添加“Settings->Build->Compiler->Java Compiler->Use compiler”选择Ajc,并在下面path中选择aspectjtools。
一个aspect类,*.aj文件。其中使用pointcut定义切点,before()、after()、returning()定义通知。最要是的是它可以被注入,和正常的bean一样使用。但声明bean时,要加入
factory-method
属性,值为aspectOf
。Spring不能实例化aspect,由AspectJ提供静态方法aspectOf()实例化一个单例。回应 2018-11-28 20:11:36 -
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; import org.junit.Test; import org.springframework.test.web.servlet.MockMvc; import spittr.web.HomeController; public class HomeControllerTest { @Test pub...
2016-07-04 21:12:08
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; import org.junit.Test; import org.springframework.test.web.servlet.MockMvc; import spittr.web.HomeController; public class HomeControllerTest { @Test public void testHomePage() throws Exception { HomeController controller = new HomeController(); MockMvc mockMvc = standaloneSetup(controller).build(); mockMvc.perform(get("/")) .andExpect(view().name("home")); } }
一直不能通过测试,异常信息如下: java.lang.NoClassDefFoundError: org/springframework/core/MethodIntrospector$MetadataLookup at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StandaloneConfiguration.requestMappingHandlerMapping(StandaloneMockMvcBuilder.java:330) at x at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder.initWebAppContext(StandaloneMockMvcBuilder.java:279) at org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder.build(DefaultMockMvcBuilder.java:200) at spitter.web.HomeControllerTest.testHomePage(HomeControllerTest.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: java.lang.ClassNotFoundException: org.springframework.core.MethodIntrospector$MetadataLookup at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) ... 28 more 求指导,就算用书中发布的代码也不能成功执行。
回应 2016-07-04 21:12:08 -
程序清单5.19中,参数Errors需要改成BindResult pom.xml中需要增加 <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.3.0.Alpha1<...
2017-03-14 22:46:28
程序清单5.19中,参数Errors需要改成BindResult
pom.xml中需要增加
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.0.Alpha1</version>
</dependency>
回应 2017-03-14 22:46:28
-
读这本书的动机 为了更全面深入了解一门技术。作为技术技术从业者,凡事探其究竟。Spring是一个在互联网从业者 广泛应用的开发框架,已经流行多年。而且凡编程都会提到这一框架。然而对其却很少深入。简单的 说一个框架知道如何用便可以应付工作中的需要。可要追本溯源,便要了解其发展。这里说大部分是 我个人理解,以及查阅资料总结所得。在最初使用spring只知道它是一个强大的web开发框架,然而 对它的强大之处却并不体会,...
2020-08-11 22:30:53
读这本书的动机
为了更全面深入了解一门技术。作为技术技术从业者,凡事探其究竟。Spring是一个在互联网从业者
广泛应用的开发框架,已经流行多年。而且凡编程都会提到这一框架。然而对其却很少深入。简单的
说一个框架知道如何用便可以应付工作中的需要。可要追本溯源,便要了解其发展。这里说大部分是
我个人理解,以及查阅资料总结所得。在最初使用spring只知道它是一个强大的web开发框架,然而
对它的强大之处却并不体会,这种强大大部分是对比EJB(即Java标准发布者发布的企业级框架)以
及当今web开发常用框架来说的。而这些主要体现在易用上。在软件的发展过程中有很多的框架,EJB
作为Java的官方发布显得更有权威一些,然而事实上却令很多开发人员抱怨其开发过于笨重,事实上
很多的开发实际上不用如此重量级的框架。简单说一半我们都需要盖一个二层小楼,而EJB提供的设备
却是盖摩天大楼用的,放在一个普通的应用身上,这不仅显得大材小用,而实际上EJB在开发上通常要
按照它的框架来盖楼,必须要遵守它的规范。然而spring正是在这一点上体现了它的超越之处,它在
开发过程中解脱了对开发者的这种束缚,当然这对于大多数应用来说,在最初,spring显然是超越了
EJB,被广泛采用;虽然spring不像EJB那种企业级标准来说能够全面覆盖到所有的面,但spring
优秀的设计思想已被接纳并经过验证;随着spring的广泛支持,它也逐渐被Java标准所吸纳,而后来
的EJB版本也引入了sping。所以Spring于EJB可能在本质上区别之处并不大,在不同时期它们或许都有
特定的意义。但spring这一框架思想被广泛认可而被逐渐接受,逐渐走向标准化;这一过程中也有许
多其它的框架产生,在这过程中spring被逐渐筛选而逐渐成为主流。
关于这本书的收获:
Spring是优秀的设计框架,我的理解这主要是得益于它的设计思想,它最初的设计是为了使应用框架
更简单和轻松(尽管优秀的框架也并不完全能达到这一点,但spring得确非常优秀),相比EJB框架
来说它的简单之处就在于不用像EJB那样,在其框架上建房子,要使用一堆臃肿甚至看似无用的代码,
来满足EJB标准的要求。在spring当中只需要简单得代码注明即可,甚至看不到痕迹。因为这一切都由
spring框架管理了起来,像EJB那样,能完成同样的功能,却能如此的优雅,我想这也是spring
设计初衷 -- “最小侵入式编程”的体现。Spring轻简的使用方式得益于依赖注入的设计,在另一方面
spring面向切面这一功能使得更多的需要可以切入到代码当中完成其它的需要,这样解决了代码复用
的问题,例如安全事务,日志等。
关于这本书得整体概括,可以说spring最核心的技术在于依赖注入(Dependency Injection)
和面向切面编程(Aspect Oriented Programming),从技术角度来看,依赖注入解决了开发过程中
耦合的问题,它通过简单的注解或配置的方式,把这种依赖交由框架管理起来,而且这种方式非常
方便易用,使得代码显得更加清晰易懂,也便于以后的管理。而在横向上,spring借鉴了面向切面这一
概念使代码功能模块实现分离,从而达到重用。这也是我认为读本书最核心要了解的知识,其中关于
这部分的讲解占据前一部分,后一部分是在各个方向的应用,如数据库,事务管理,以及在工程项目
当中的应用。
Spring实战这本书涵盖了Spring框架核的心思想,即是Dependcy Injection (DI)依赖注入,和Aspect Oriented Programming(AOP)面向切面编程;同时这本书也在其核心思想基础上向各个方向展开,数据库,事务管理等等。往往经典的框架都是简单易用的。Spring或许应了这句话,当初也正是因为Sun公司发布的EJB框架没能满足这样需求,在实际应用中显得臃肿而复杂。这也便是spring成为流行趋势的原因。对比EJB,它要求使用者必须继承它的框架,遵从它的规范来进行开发,在一个企业级应用开发中,开发人员所期望创建的流程必须在EJB所规定的框架之下;然而spring打破了这样的束缚,它让开发自由度更大,释放了这种规范的要求,这在思想上就高了一筹;而且spring避免了EJB代码开发中高度的耦合与复杂的场景这也得益于spring框架DJ和AOP的好处,让java开发变得简单这一趋势所产生的。
回应 2020-08-11 22:30:53 -
Spring核心 “我的建议是尽可能地使用自动配置的机制。显式配置越少越好。当你必须要显式配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),我推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML”。 自动化装配bean Spring从两个角度实现自动化配置 组件扫描(component scanning) 自动装配(...
2018-11-28 20:11:36
Spring核心
“我的建议是尽可能地使用自动配置的机制。显式配置越少越好。当你必须要显式配置bean的时候(比如,有些源码不是由你来维护的,而当你需要为这些代码配置bean的时候),我推荐使用类型安全并且比XML更加强大的JavaConfig。最后,只有当你想要使用便利的XML命名空间,并且在JavaConfig中没有同样的实现时,才应该使用XML”。 引自 Spring in action 自动化装配bean
Spring从两个角度实现自动化配置
组件扫描(component scanning) 自动装配(autowiring) 引自 Spring in action @Component注解
表明该类会作为组件,并告知Spring要为这个类创建bean,不需要显示配置bean。
为bean命名:@Component("Name")
@ComponentScan注解
组件扫描默认是不启用的,需要使用该注解用以下方式启用:在配置类上标注即可。 默认情况下只扫描当前包及其子包。也可以设置组件扫描的基础包:
@ComponentScan("Name") @ComponentScan(basePackages="Name") @ComponentScan(basePackages={"Name1", "Name2", ...}) @ComponentScan(basePackageClasses={Name1.class, Name2.class}) 引自 Spring in action @Autowrited注解
自动装配,可以使用在构造器,方法,属性之上以获得自动装配。当没有匹配的组件时,会抛出异常。设置required属性为false可以避免抛出,但要十分谨慎检查对象是否为null。如果多个对象可以匹配,同样抛出异常。
@Named、@Inject注解
与 @Component注解、@Autowrited注解有细微差别大多情况下可以替换使用,来源于Java依赖注入规范(Java Dependency Injection)。
@ContextConfiguration注解
@ContextConfiguration(classes=*.class)用于标记加载配置类位置。 @ContextConfiguration({"classpath:*.xml"})用于标记加载配置xml文件位置。
@RunWirh
运行器
基于Java的配置
@Bean
声明bean。产生单例对象。唯一限制java方式配置的是java语言特性。
基于XML的配置
构造器注入 <cnstructor-arg>
id表示标;class类名;注入单值时使用value属性;应用其他bean时使用ref属性。 使用命名空间c装配,声明c的URI后可以使用 c: 构造器参数名[-ref]="value" 形式装配。也可以使用参数顺序编号代替参数名,c: _index[-ref]="value" ,当只有一个参数时可以省略编号。
属性注入 <property>
id表示标;class类名;注入单值时使用value属性;应用其他bean时使用ref属性。 使用命名空间p装配,声明c的URI后可以使用 p: 构造器参数名[-ref]="value" 形式装配。也可以使用参数顺序编号代替参数名,p: _index[-ref]="value" ,当只有一个参数时可以省略编号。
装配集合
<list> <set> <map> <props> 引自 Spring in action <list><value>value</value></list>
然而c或者p命名空间并不能装配集合,使用util命名空间:
<uilt:list> <uilt:set> <uilt:map> <uilt:props> 引自 Spring in action <util:list id="name"><value>value</value></util:list>
之后使用id属性引用它。
导入和混合配置
@Import @ImportResource 标签
在java配置中使用
@Import({*.class, ...})
导入其他配置类,使用@ImportResource("*.xml")
导入xml配置。<import>标签
在xml配置中使用
<import>
标签导入其他xml配置,使用<bean>
标签导入java配置类。profile
有选择的配置bean
在java配置类中配置
在类上使用
@profile("name")
配置,只有在"name" profile激活时词才会创建。在方法上使用时,可以在一个配置类中声明不同的profile。没有声明的bean无论激活哪个profile都会创建。在xml中配置
在
<beans>
标签中配置profile
属性。激活profile
设置
spring.proflies.active
和spring.profiles.default
。如果设置active,就按active;未设置active,则按default;均未设置,没有激活的profile。激活的方式有很多,目前还不是太了解那些条目是什么意思。只知道在测试类上可以使用@ActiveProfiles("name")
设置。条件化bean
@Conditional标签
@Conditional(*.class)
标记bean,类实现Condition接口,实现接口中的matches方法,返回一个boolean,ture创建bean。 Condition接口:public interface Condition { boolean matches (ConditionContext ctxt, AnnotatedTypeMetadata metadata); }
自动装配的歧义
@Primary标签
标记首选bean,在xml配置中使用bean的primary属性设为true。
@Qualifier标签
可以与
@Autowrited
和@Inject
协同使用,指定要注入的是哪个bean。限定符与bean的ID相同,这样当重构bean时ID可能有变化,自动装配可能会失败,自定义限定符。声明bean时候与@Component
组合使用,@Qualifier("name")
。自定义限定符注解
一个java类,形式如下:
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementTypt.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface Name {}
通过使用多个
@Name
标签限定bean装配。Bean作用域
默认情况下是单例(Singleton)的。还包括原型(Prototype)、会话(Session)、请求(Request)。
@Scope标签
使用
@Scope("name")
设置。可以是字符串,但是使用ConfigurableBeanFactory
更不容易出错。如果使用xml配置使用bean的scope属性。会话和请求作用域
预留
属性占位符(Property placeholder)
@PropertySource("path")
声明属性源,从属性源中获取值,使用Environment的getProperty()方法。getProperty()有重载方法,用于类型转换。getRequiredProperty()属性不存在是抛出异常的getProperty()版本。 还有String[] getDefaultProfiles()和String[] getActiveProfiles()获取那些profile处于激活的状态。占位符${...}
为了使用占位符需要配置一个类:
@Bean public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); }
如果使用xml:
<context:property-placeholder />
在xml中直接使用。在自动扫描和java配置中,用
@Value("&{...}")
标签,在属性前使用。SpEl
表达式形式如
#{...}
。很灵活。使用 T()
引用java类,之后通过.访问静态方法、静态属性 使用beanID引用bean,调用方法,属性 使用systemProperties
引用系统属性 在xml和@Value
中组合使用 调用方法时在.
之前使用?
,如果是null
值则不调用该方法 使用运算符和正则表达式(字符串matches
表达式) 使用[index]
引用集合元素,获取字符串字符.?[表达式]
,返回集合中表达式为真的子集.^[]
和.$[]
,查询第一个和最后一个匹配项.![属性]
,选择属性到新集合中引自 Spring in action 后四个对于集合使用。组合起来非常灵活。
Spring AOP
Spring只支持方法级别的连接点。切面要声明为一个bean。
通知
五种类型
前置通知before 后置通知after 返回通知after-return 异常通知after-throwing 环绕通知around 引自 Spring in action 连接点
可以插入通知的位置
切点
插入通知的位置
切面(Aspect)
通知和写点共同定义了切面
引入(Introduction)
向现有类添加新方法
织入(Weaving)
把切面应用到目标对象并创建新的代理对象的过程,多个点可以织入:
编译期,AspectJ织入方式 类加载期,需要特殊的类加载器,AspectJ5的加载时织入支持 运行期,SpringAOP织入方式 引自 Spring in action 编写切点
execution(返回值类型 方法所属类.方法(参数类型)) [操作符 指示器]
返回任意类型时使用*
,使用任意参数时使用(..)
,可选的操作符指示器,例如指示器arg等。bean指示器用于选择特定id的bean。使用注解创建切面
使用@Aspect标记切面。@Before @After @AfterReturing @AfterThrowing注解,使用
注解(切点)
的方式在方法上使用。使用方法名称引用切点:
@Pointcut(切点) 方法名称() {}
@EnableAspectJAutoProxy注解
在JavaConfig中启用自动代理,xml中使用
<aop:aspectj-autoproxy>
环绕通知
@Around注解注释环绕通知,被环绕的方法必要的
ProceedingJoinPoint
类型参数。并调用proceed()
方法执行被通知方法。处理参数
execution(返回值类型 方法所属类.方法(参数类型)) [操作符 指示器]
使用
args(参数名称)
指示器,在注解中加入参数名称,参数名称要与切点方法签名中的方法名称匹配。通过直接引入新功能
@DelcareParents(value="bean类型", defaultImpl=实现类.class) public static 功能接口
在xml中声明切面
<aop:config>
从它开始。<aop:aspect ref="bean">
定义切面,ref提供方法。<aop:before|after|after-returning|after-throwing pointcut="切点" method="方法">
通知。<aop:pointcut id="name" expression="切点">
定义切点。<aop:around>
环绕通知。传递参数时候,在xml文件中使用and
等代替&&
。<aop:declare-parents types-matching="bean类型" implement-interface="功能接口" default-impl="实现类"|delegate-ref="bean">
引自 Spring in action 注入AspectJ切面
注意: 使用idea,需要在设置中添加“Settings->Build->Compiler->Java Compiler->Use compiler”选择Ajc,并在下面path中选择aspectjtools。
一个aspect类,*.aj文件。其中使用pointcut定义切点,before()、after()、returning()定义通知。最要是的是它可以被注入,和正常的bean一样使用。但声明bean时,要加入
factory-method
属性,值为aspectOf
。Spring不能实例化aspect,由AspectJ提供静态方法aspectOf()实例化一个单例。回应 2018-11-28 20:11:36
论坛 · · · · · ·
第四版的第四章的源码,找了好多都没有,谁那里有... | 来自fanchaoo | 1 回应 | 2016-10-27 17:08:24 |
这本书的其他版本 · · · · · · ( 全部11 )
-
Manning Publications (2011)8.5分 98人读过
-
人民邮电出版社 (2006)7.4分 396人读过
-
人民邮电出版社 (2013)7.9分 266人读过
-
人民邮电出版社 (2008)7.7分 219人读过
以下书单推荐 · · · · · · ( 全部 )
- Web编程与设计 (敏子爱书)
- 3.Java (葡萄)
- java高级软件工程师 (猫王)
- 计算机专业必读经典书籍(知乎整理) (草莓)
- (极客时间)左耳听风专栏推荐书单 (Gunilla)
谁读这本书?
二手市场
订阅关于Spring实战(第4版)的评论:
feed: rss 2.0
1 有用 Carius 2018-07-15 10:10:39
适合初学者对于想了解spring整个体系的朋友。因为主题太大了,导致内容还是太浅了,可对于初探来说也是足够了。开始几章DI,AOP讲得挺好的,后面的Spring Data总结的也不错。
4 有用 payall4u 2017-10-20 20:39:16
书太追求全面了,本身是本教程,不是cookbook。但作为教程不够深(几乎所有配置都用注解),作为cookbook不够广。
5 有用 卡列宁的微笑 2018-07-25 22:25:19
我还是觉得看书比看文档效率高。这本书覆盖了Spring框架最重要和本质的部分,介绍了这个框架的设计思想,还举了很多有趣的例子,很适合大概了解。
1 有用 PandaHermit 2018-09-21 17:13:43
各方面讲的蛮清楚,很好的指导书。
2 有用 acAric 2016-12-22 22:43:39
基本上涵盖了spring的方方面面。spring已经占据java的大半江山了,特别是出了spring boot之后,更加易用。又基于boot适用于最新的微服务架构,配合cloud,搭建分布式集群架构。spring在未来几年依然会走在前列,并且地位越来越重要稳固。这本书中也结合讲了boot,以及mq的应用,很全面。可以当做参考书,只是最新的spring cloud没有讲到,遗憾。
0 有用 我家门前有阳光 2022-04-19 18:43:42
不错的入门书
0 有用 DancingWing 2022-02-13 01:21:45
还没看完,很适合入门
0 有用 阿里阿里巴巴 2021-12-13 14:45:12
内容比较杂乱
1 有用 我是看剧小能手 2021-11-30 11:18:00
很全面,In Action系列的书其实都很不错,相关的Action书籍看了很多!推荐,值得一看!
1 有用 星痕*猴子 2021-11-03 14:48:02
前几章的知识含量较高,讲了Spring的核心思想和设计模式,包括DI、AOP和MVC这些。10章以后的章节知识含量偏低,主要是Spring核心思想在各协议和领域的实现,没有新意,读一遍就可以了。