《Spring+in+action+中文版(第4版)》读书笔记

1 Spring到底做了什么?
Spring通过面向pojo编程、DI、切面和模板技术来简化java开发的复杂性!
2 Bean装配
Spring容器负责创建应用程序中的bean并通过DI来协调这些对象之间的关系。Spring提供3中装配机制:
在xml中进行显式配置
在java中进行显式配置
隐式的bean发现机制和自动装配
无论哪种配置或者综合配置最终都是实现了两个功能:声明bean和装配bean;
其中java显示配置和xml显示配置可以交叉引用
单元测试读取spring bean
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:./config/applicationContext.xml”)/@ContextConfiguration(classes = CDPlayerConfig.class)
3 配置profile bean
说明:轮廓、剖面意思。
用于进行bean的选择性生成,可以应用在部署、开发、生产环境的时候进行多数据库的配置。
使用方法:
3.1 正常配置bean方式只是在java中需要交@Profile(对应bean的唯一标志位)注解;xml中注入需要配置
3.2 配置了多少profile现在需要进行激活,激活方式需要配置Spring.profiles.active(default)属性,可以作为dispatcherServlet的初始化参数或者作为web应用上下文参数进行配置,例如在web项目中,在web.xml文件配置:

spring.profiles.default
dev
3.3 单元测试使用profile
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(“classpath:./config/applicationContext.xml”)/@ContextConfiguration(classes = CDPlayerConfig.class)
@activeprofiles(“dev”)
4 Spring 4.0提供比上述profiles更好的条件化创建bean方式:@conditional(有条件的;假定的)
实例的应用是判断当前电脑系统,win 文件存在哪,linux 文件存到那:https://www.cnblogs.com/dyppp/p/7732084.html
5 Spring Bean 的作用域
四种作用域,单例(singleton)(默认),原型(prototype)、会话(session)、请求(ruquest)
单例或原型可以使用@scope注解或者xml中的scope=“prototype” (这是原型),来进行设置
会话或请求需要使用代理的方式进行设置,proxyMode=ScopedProxyMode.INTERFACES或者xml配置aop:scoped-proxy 默认使用
6 外部文件(属性文件)注入
6.1 在java中使用@PropertySource注解和Environment
例如:

6.2 在xml中加入
context:property-placeholder/
之后使用${cas}或的数据
7 SpringEL =spring expression language spring表达式语句
和6的的外部文件注入类似,springEL 使用的是#{} 来进行注入标识使用方式
使用方式
7.1 将bean 属性装配到另一个bean属性中, =》#{beanid.property}
7.2 将bean方法装配到另一个bean中 =》#{beanid.mothed}
7.3 Java 中使用上springEL进行装配,使用@Value注解,例如属性值cas可以设置成
@Value(‘#{cas,properties[cas.url1]}’)
8 Spring AOP
AOP术语解释(实际上不是很准确,但是没办法都这么说,只能记录了):
通知(advice):指的是切面的工作,就是切面主要是干什么的,什么时候使用切面。Spring切面定义了5中类型通知,前置通知、后置通知、返回通知、异常通知、环绕通知。
连接点(Join point):是在应用执行过程中能够插入切面的一个点,切面代码可以利用这些点插入到应用插入到应用正常流程中,并添加新的行为。
切点:(poincut)切点定义了切面工作的具体的点,比通知更加的精确
切面:(aspect):通知+切点
引入(introduction):运行我们向现有类添加新的方法和属性
织入(weaving):是把切面应用到目标对象并创建新的代理对象的过程。在目标的生命周期里有多个点可以进行织入:编译期,类加载期、运行期(spring AOP默认是使用这个方式,使用代理的方式,所有spring只支持方法级别的连接点)
使用AOP 两种方式,javaconfig或者xml
首先定义切面:

一般使用xml方式:aop:aspectj-autoproxy //启动Aspectj自动代理
//声明bean
JavaConfig方式:
9 SpringMVC介绍
9.1 Mvc中测试控制器(controller)方式
@Test
public void testHomePage() throws Exception {
SystemController system = new SystemController();
MockMvc mockMvc = standaloneSetup(system).build();
mockMvc.perform(get("/system/tyaq"));
}
9.2 RequestMapping 可以接受String 类型的数组,这个需要了解,一直是使用一个,以后根据情况可以使用RequestMapping{“/a”,”/b”}
9.3 Spring MVC 允许多种方式将客户端信息发送的控制器的处理器方法中:包括
查询参数(Query Parameter):?传参,控制器@RequestParam()
表单参数(From Parameter):参数:User user
教研表单,在user上属性中加注解@notnull 或者其他注解,之后再参数中增加@Vaild User user,Errors errors 进行检验:

路径参数(Path Parameter):如tyaq/ghf ,控制器 上部@RequestMapping(value=”/tyaq/{name}”),参数:@PathVariable(“name")
10 Spring异常处理的两种方式
10.1 将异常映射为http转态码,spring提供多种方式将异常转换为相应
特定的spring异常将自动映射为指定的http转态码
异常上可以添加@ResponseStatus注解,从而将其映射为某一个http转态码
10.2 在方法上可以添加@ExceptionHandler(自定义的异常.class)注解,使其用来处理异常,当遭遇之定义异常时候回执行自定义异常处理流程
10.3 使用控制器通知@ControllerAdvice
实际上是将多个@ExceptionHandler,汇总到一块
Spring会自动扫描controllerAdvice,之后任意控制器方法抛出DupExceptiong.class方法后,都会调用dupHandler()方法来进行处理
11 Spring跨重定向请求传递参数
11.1 使用URL路径模板以路径变量和/或者以查询参数的形式
这个方式只可以传递String的一个字符串,无法传递模型数据
实例:

或者(注意这种,以站位符方式,所有不安全的字符都会进行转义,更安全)

11.2 使用flash属性发送数据
可以传递模型属性
实例:

重定向方法直接使用模型数据。
12 Spring web flow 看着有点晕了,没看懂(稍后再看看)
大体上是说,web flow 是工作流的一直实现。Spring开启 spring web flow 必须使用xml配置的方式,没有javaconfig配置方式。
首先使用xml配置中创建一个流程执行器

之后配置流程注册表,就是实际的流程,
最后在jsp页面根据注册表,添加各种挑战链接。
13 Spring Security spring安全框架
Security 的核心是 serverlet的filter 过滤器
使用:1在web.xml中配置security的代理。

或者在java中的bean配置也可以。
一代而过,感觉没有什么的新鲜知识。
14 非关系型数据库介绍
MongoDB持久化的的文档数据库,主要针对一个一个独立实体储存的数据,例如学校学生数据,一个学生是一个独立个体。
Redis持久化的key-value类型数据。
15 Spring对缓存的支持
Spring对缓存的支持有两种方式:
15.1 注解驱动的缓存

15.2 xml声明的缓存

使用的时候在方法上添加@Cacheable(去缓存x中找数据)和@CacheEvict(清除缓存x)就行.
15.3 使用Ehcache
java配置

Xml需要配置。
15.4 使用Redis缓存

Spring可以使用多少缓存管理器。
Spring的缓存抽象很大程度是围绕切面构建的!
16 Spring 方法级别的安全
Spring Security 方法级别的安全是spring web 级别安全的重要补充,主要是基于注解@RolesAllowed,@PreAuthorize,@PostAuthorize,另外还看到通过@PreFilter和PostFilter过滤方法的输入、输出。
17 Spring 使用远程服务
17.1 Spring RMI

RMI缺点:1.RMI很难穿越防火墙,这是因为RMI使用任意端口来交互;
2.RMI是基于java开发,意味着客户端和服务端都必须使用java开发,因为RMI使用了java 序列化机制,所有通过网络传输的对象类型必须保证在调用两端的java运行中是完全相同的版本。
具体使用(自己测试2个springweb容器中):
服务端配xml









服务端方法:
public interface RmiService {
Integer getAge(int age);
}
public class RmiServiceImpl implements RmiService {
@Override
public Integer getAge(int age) {
age=age+1;
return age;
}
}

客户端配置xml:



    

客户端方法,需要有写接口方法:
public interface rmiservice {
Integer getAge(int age);
}
使用:当成正常的本地bean使用就行,面向接口编程
@Resource
private rmiservice rmiservice;
Integer asdf = rmiservice.getAge(2);
System.out.println(asdf);
结果是3:!
17.2 Spring使用Hessian和Burlap进行远程调用。
这两种方式是基于http的轻量级的远程服务解决方案。所有肯定需要配置url访问路径,也就是需要配置控制器,接收请求路径。
Hessian和RMI一样,使用二进制消息进行客户端和服务端的交换。但与其他二进制远程调用技术(RMI)不同的是,它的二进制消息可以移植到其他非java语言中。
Burlap是基于XML的远程调用技术,相比Hessian可读性更好。
调用示意图:

因为Hessian和Burlap都是基于HTTP的,它们都解决了RMI所头疼的防火墙渗透问题。但是当传递过来的RPC消息中包含序列化对象时,RMI就完胜Hessian和Burlap了。因为Hessian和Burlap都采用了私有的序列化机制,而RMI使用的是Java本身的序列化机制。如果我们的数据模型非常复杂,Hessian/Burlap的序列化模型就可能无法胜任了。
我们还有一个两全其美的解决方案。让我们看一下Spring的HTTP invoker,它基于HTTP提供了RPC(像Hessian/Burlap一样),同时又使用了Java的对象序列化机制(像RMI一样)
17.3 Spring的HttpInvoker
HttpInvoker 和Hessian(Burlap)非常类似,使用方式一模一样。

要记住HTTPinvoker有一个重大的限制:它只是一个Spring框架所提供的远程调用解决方案。这意味着客户端和服务端必须都是Spring应用。并且,至少目前而言,也隐含表明客户端和服务端必须是基于Java的。另外,因为使用了Java的序列化机制,客户端和服务端必须使用相同版本的类(与RMI类似)。
17.4 基于SOAP的web服务
以上四种都是远程调用的可选解决方案,但是面临无所不在的远程调用的时候,以上几种还是有很大的缺陷,Web服务是很好的解决方案。即我们经常会看到的Webservice服务。
调用过程图:

18 Spring REST API
18.1 REST 是 Representation State Transfer,表叙性转态转移的意思!就是说将资源的转态以最合适的客户端或者服务端的形式从服务器转移到客户端(或者反过来)!通过的路径是HTTP方法,具体来说就是GET、POST、PUT、DELETE等。REST也可以说是一种应用之间的通信方式!
18.2 Spring对REST的支持主要通过6个方面:控制器处理所有HTTP方法;借助@PathVariable注解,将变量作为URL路径的一部分;借助Spring的视图或视图解析器可以将模型数据渲染为XML、Json等;借助ContentNegotiatingViewResolver来选择最合适的客户端表述(我从没用过);借助@ResponseBody注解和HttpMethodConverter实现来替换基于视图的渲染方式或将传入的HTTP数据转换为传入控制器处理的Java对象;借助RestTemplate,spring能够方便的使用Rest资源!
18.3 Spring提供两种方式将资源的Java表达方式转换为发送客户端的表述形式!
18.3.1.1 内容协商(Content negotiation)不解释了,不怎样用
18.3.1.2 消息转换器(Message Converison)常用!最常用的事@ResponseBody注解
18.4 发送错误消息到客户端
18.4.1.1 使用@ResponseStatus注解指定转态码
保存成功实例:

18.4.1.2 控制器方法返回ResponseEntity对象

18.4.1.3 异常处理应对错误场景!

18.5 编写REST客户端
18.5.1.1 使用HTTPClient等方式(不推荐)

18.5.1.2 使用RESTTemplate
举例说明:
18.5.1.2.1.1 检索资源

或者

19 Spring 消息
以上RPC服务各种实现都是同步的消息执行,客户端调入时候,程序会阻塞等待服务端执行完成;而基于消息的远程调用时异步执行的!
Spring消息大致分为两类JMS(java message Service)java消息服务和AMQP(advanced message queuing Protocol)高级消息队列协议
异步消息有两个重要的概念:消息代理(message broker)和目的地(destination)。当一个应用发送消息时候,会将消息给一个消息代理。
消息代理可以确保消息被投递到指定的目的地,同时解放发送者,使其继续进行其他业务处理。
目的地不是指消息发送到哪里,而是指的是消息发送到发送者的某个区域由接受者进行调用接收。尽管不用的消息系统会提供不同的消息路由模式,但是有两种通用的目的地队列(Queue)和主体(Topic)每种类型都与特定的消息模型相关联,分别是点对点模型(队列)和发现/订阅模型(主题)!
实际上就是把消息发送到第三方应用,由第三方进行消息中转!
19.1 JMS 使用
ActiveMQ消息代理,下载启动!
Spring发送端配置bean

或是使用spring的配置文件中声明的amq命名空间

之后声明目的地:

使用Spring的jmsTemplate进行消息发送

Java代码进行消息发送:

在发送消息时候,可以使用消息转换器对消息进行转换,例如转换成json格式数据:

接收端接收消息!

同样可以使用消息转换器进行转换:(不需要配置bean)

以上的JMSTemplate接收消息的最大缺点在receive()和receiveAndConvert方法都是同步的,意味着这些方法一直被阻塞直到有可用消息(或者直接超时),解决办法就是:使用消息驱动POJO:
使用方式:
实现监听器,添加注解!

另一种方式(推荐)
配置监听器!之后实现代码!

基于JMS的RPC,spring提供JmsInvokerServiceExporter,它可以把bean导出为基于消息的服务!为客户端提供了JmsInvokerProxyFactoryBean来使用这些服务!
发送消息!

接收消息!

19.2 使用AMQP实现消息功能
AMQP比JMS更好!更优秀!多了一个Exchange模块,可以进行规则配置,放消息到多个队列!

使用:
安装RabbitMQ,开源的消息代理,类似ActiveMQ
发送端Spring配置

类似ActiveMQ不在叙述!
20 使用WebSocket和STOMP实现消息功能
WebSocket提供了一个套接字实现双公示通信的功能!可以应用于各种应用,但是应用最大的还是实现服务器和基于浏览器的应用之间的通信!
20.1 Spring低级别的WebSocket API
Java代码:
Java配置

Xml配置:

JavaScript客户端配置:

20.2 Spring应对不支持WebSocket的浏览器的解决办法(SockJS)
SockJS会首先使用WebSocket方法进行通信,不支持更换其他方式:包括 XHR流、XDR流、iFrame事件源等等。使用上和之间时间WebSocket方式类似!
Java代码:
Java配置:

Xml配置:

JavaScript端配置:

SockJS使用的URL是http://或者 https://,替换上面的ws://或者wss://,只需要修改下面两个部分!

20.3 使用STOMP消息
STOMP是简单文本导向消息协议,是针对websocket的一个传输协议!类似于HTTP协议是在TCP套接字上添加的请求-响应模型一样!STOMP的消息格式和HTTP格式类似:如下

这个发送消息的目的地,可以是应用内存或者是消息代理(ActiveMQ或者RabbitMQ)
启用STOMP消息功能:
Java代码:
Java配置:

ConfigureMessageBroker方法可选,不使用,消息基于内存,不适合集群操作。启用的话可以基于RabbitMQ或ActiveMQ!学名叫做启用代理中继!逻辑图如下:

处理来自客户端的STOMP消息:

和requestMapping类似!同样的可以使用消息转换器(类似@ResponseBody)对消息进行转换!
@SubscribeMapping 和@messageMaping类似;不同在于SubscribeMapping主要场景是实现请求-回应模式!
编写javaScript客户端:

发送消息到客户端:
到目前为止,客户端负责了所有的消息发送,服务器只能监听这些消息!现在实现服务器发送消息到客户端!
spring提供两种发送数据到客户端的方法:

  1. 作为处理消息或处理订阅的附带结果!
  2. 使用消息模板!
    第一种实例:

或者

@SubscribeMapping的区别在于这里的shout消息捋会直接发送给客户端,而不必经过消息代理。如果你为方法添加asendTo注解的话,那么消息捋会发送到指定的目的地,这样会经过代理。
第二种实例:

同时控制器中还可以处理用户消息和给特定用户发送消息!
21 配置Spring发送邮件
Spring上下文中配置邮件发送器:

或许使用JNDI

转配和使用邮件发放:

使用模板配置email消息
21.1.1.1 第一种使用Apache Velocity
需要将VeocityEngine装配
模板文件

使用:

21.1.1.2 使用Thymeleaf构建email消息
模板

22 使用JMX管理Spring bean
JMX 是java management extension的简写,是java管理的拓展,主要应用在可以在spring运行中本地或者远程的对ioc容器中的bean进行增删改查。核心组件是托管bean(managed bean,MBean),指的是暴露了特定方法的JavaBean,这些接口定义了管理接口!
使用思路是:使用Spring的JMX模块将Spring Bean导出为模型Mean,之后就可以正常对bean进行修改!
22.1 本地 Mbean导出使用
使用过程:
Java代码:
将ioc中的bean导出为模型Mbean

有些bean属性或者方法是不需要暴露的,这时候Mbean的信息装配器(Mbaen info accessor)就起到用武之地了!有两种装配器,一种装配需要暴露的bean方法或属性(MethodNameBasedMbeanInfoAssembler),一中装配不需要暴露的bean方法或属性(MethodExclusionMBeanInfoAssemble)!以一种为例,最后为了使装配器生效,将它装配近MbeanExporter中。

当有多个Bean需要导出的时候,上面基于方法名称的方式不好用了,这时候有一种使用接口定义Mbean的操作或属性!Spring的InterfaceBasedMbeanInfoAssmber可以使用接口来选择bean的那些方法需要暴露为Mbean的托管操作!
使用:
定义接口:

最后一种,也是推荐的方式,使用注解驱动的MBean
使用:xml中配置

Java中配置:

以上3中方式都可以在MBean服务器(依赖应用服务网环境例如Tomcat,没有容器环境的换需要,在xml配置content:mbean-server)注册Mbean,如果注册Mbean冲突,有相同的名称,默认是失败的!可以用registrationBehaviorName属性来进行配置,可以修改为覆盖、忽略、失败三种形式!
22.2 远程MBean使用
使用远程Mbean肯定要和多种远程访问协议结合!
使用RMI远程MBean方式:
创建MBean服务端(被访问端)

创建客户端(访问端)1:

顾名思义,MBeanServerConnectionFactoryBean是一个可用于创建Mbeanserver-
Connection的工厂bean。由MBeanServerConnectionFactoryBean所生成的MBeanServerConnection实际上是作为远程MBean服务器的本地代理。它能够以MBeanServerConnection的形式注入到其他bean的属性中:
使用:

常用操作:

创建客户端(访问端)2(推荐使用):
使用代理(MBeanProxyFactoryBean)的方式,可以让我们直接访问远程的MBean就如同本地的bean一样!

配置方式:

还是需要1方法中配置的链接注入进去,同时还设置了接口的配置器!最后返回代理实例!
22.3 JMX通知

Spring通过NotificationPublisherAware接口来提供发送通知的支持,任何希望发送通知的MBean都必须实现这个接口!
发送通知:

接收MBean通知的标准方法是实现avax.management.NotificationListener接口。

同时要在MBean服务端增加监听器!

有一些图片没办法,整体粘贴,上传到csdn了!
https://download.csdn.net/download/guohangfei001/11146620

你可能感兴趣的:(java)