基于《Spring实战》第五版进行学习
让我们来一起学习Java Spring吧!
Spring 的核心是一个容器,通常称为 Spring 应用程序上下文,用于创建和管理应用程序组件。**这些组件(或 bean)**在 Spring 应用程序上下文中连接在一起以构成一个完整的应用程序。
将 bean 连接在一起的行为是基于一种称为 依赖注入(DI)的模式。依赖项注入的应用程序不是由组件自身创建和维护它们依赖的其他 bean 的生命周期,而是依赖于单独的实体(容器)来创建和维护所有组件,并将这些组件注入需要它们的 bean。通常通过构造函数参数或属性访问器方法完成此操作。
如product service依赖(即内部需要一个)inventory service,在Spring中其框架如下:
传统方式是使用XML进行配置:
但是上面的方式不太放便,现在常用的是利用Java注解的方式:
@Configuration:向spring表明其是一个配置类
public class ServiceConfiguration {
@Bean:指示其返回的是一个Bean组件
public InventoryService inventoryService() {
return new InventoryService();
}
@Bean:同上,同时还依赖了上一个bean
public ProductService productService() {
return new ProductService(inventoryService());
}
}
使用注解的方式是基于自动配置和自动扫描。
现在可以利用https://start.spring.io/实现快速的Spring项目框架搭建。
有关Spring的注解详情,可参看:Spring注解与测试。
Spring MVC是Spring附带的web框架,核心是控制器的概念,其是一个处理请求并使用某种信息进行响应的类。
MVC即是:model-view-controller。
其中,controller主要负责处理相应的网络请求,并使用JSP或Themleaf等模板来设计视图(可视化对应的模型)。模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器
如何利用Spring MVC进行Web应用的开发,可见开发Web应用。
Spring框架下提供来JDBC和JPA来简化和规范与数据库的交互,大大简化了编写持久化层操作的时间——Spring处理数据库。
应用程序安全性一直是一个重要的主题,而且似乎一天比一天重要。幸运的是,Spring 在 Spring security 中有一个健壮的安全框架。
Spring Security 解决了广泛的应用程序安全性需求,包括身份验证、授权和 API 安全性。
https://potoyang.gitbook.io/spring-in-action-v5/di-4-zhang-spring-an-quan
前面已经说到,spring有两种配置:
值得一提的是,Spring的环境是所有可配置属性的汇总,包括:
它将上述四种属性汇总到一个环境中,以至于其内的Bean都可以互相调用或注入。
Spring配置属性包括服务器、web页面、数据库等等,建议需要配置相关属性的时候再去查询,但是需要提前看看能够配置什么东西,以便在工作时更好地去查找。
Spring框架自己已经功能强大,但还可以通过与其他应用程序集成而变得更强!
什么是REST服务?
REST不是”rest”这个单词,而是几个单词的缩写 REpresentation State Transfer,直接翻译:表现层状态转移。比较通俗的说法是:URL定位资源,用HTTP动词(GET,POST,DELETE,PUSH等)描述操作。
什么是RESTful?
基于REST构建的API就是Restful风格。
为什么使用Restful?
传统的开发方式是用JSP来作为表现层,这有一个缺点:需要将前端的静态HTML页面转换为JSP页面,降低了开发效率,并且让后端人员还需要关注前端的页面。为了应对这个问题,采用前后端分离。并且Restful可以统一给PC、微信(H5)、IOS或Android提供服务,服务器至提供数据,不提供前端样式(前端样式就由前端来关注!)
restful详情请见:restful。
restful实例详见:实例。
如何使用Rest API?
Spring 应用程序可以通过以下方式使用 REST API:
RestTemplate —— 一个由 Spring 核心框架提供的简单、同步 REST 客户端。
Traverson —— 可感知超链接的同步 REST 客户端,由 Spring HATEOAS 提供,灵感来自同名的 JavaScript 库。
WebClient —— 一个在 Spring 5 中引入的响应式、异步 REST 客户端。
Spring可以使用JMS来发送洗哦阿西,也可以使用RabbitMQ以及AMQP、Kafka等消息中间件来实现消息的发送。
Spring 通过称为 JmsTemplate 的基于模板的抽象来支持 JMS。使用 JmsTemplate,很容易从生产者端跨队列和主题发送消息,并在消费者端接收这些消息。Spring 还支持消息驱动 POJO 的概念:简单的 Java 对象以异步方式对队列或主题上到达的消息做出响应。
使用 Spring 配置,可以将多个组件组装到数据流经的管道中。从而实现不同组件之间的消息通过传输管道来互相传递。
那么如何配置集成流(即定义数据流向)呢?
上述代码的重点在倒数几行:定义了两个channel,并设定了两者之间的数据传输方式,最后的fileWriterChannel通道利用int-file命名空间配置了一个外部通道适配器,将消息写入文件中。
@Configuration
public class FileWriterIntegrationConfig {
@Bean
@Transformer(inputChannel="textInChannel", outputChannel="fileWriterChannel")
public GenericTransformer upperCaseTransformer() {
return text -> text.toUpperCase();
}
@Bean
@ServiceActivator(inputChannel="fileWriterChannel")
public FileWritingMessageHandler fileWriter() {
FileWritingMessageHandler handler =
new FileWritingMessageHandler(new File("/tmp/sia5/files"));
handler.setExpectReply(false);
handler.setFileExistsMode(FileExistsMode.APPEND);
handler.setAppendNewLine(true);
return handler;
}
}
@Configuration
public class FileWriterIntegrationConfig {
@Bean
public IntegrationFlow fileWriterFlow() {
return IntegrationFlows
.from(MessageChannels.direct("textInChannel"))
.transform(t -> t.toUpperCase())
.handle(Files.outboundAdapter(new File("/tmp/sia5/files"))
.fileExistsMode(FileExistsMode.APPEND)
.appendNewLine(true))
.get();
}
}
**注:**IntergrationFlow是Spring中的集成类。
使用Spring Integration的DSL可以实现怎样的功能?
集成流由以下一个或多个组件组成:
**注:**所谓Spring集成就是实现多个组件之间的数据交互;
Reactor就是一个常用的事件反应模型。
当我们开发应用程序时,有两种风格的代码我们可以写——命令式和响应式:
命令式(同步式) 的代码是一套串行任务,每次运行一个,完成前一个任务后再完成后一个。数据是批量进行处理的,在前面的任务没有完成批量数据处理前,不能将工作移交到下一个任务。
响应式 定义一组任务去处理数据,但这些任务可并行运行。每个任务处理这些数据的一个子集,当它处理另外一个子集的时候,把处理完成的数据交给下一个任务。
应用于一个真实世界的类比就是,**将命令式编程看做一个装水的气球,响应式编程看做花园里面的水管。**两者都是在炎热的夏天让你的朋友惊喜并沉浸其中的方式。但是它们的执行风格是不同的:
命令式 一个水气球一次能携带的它的有效载荷,在撞击的那一刻浸湿了它预定的目标。然而,水球的容量是有限的,如果你想用水泡更多的人(或把同一个人淋得更湿),你唯一的选择就是增加水球的数量。
一根花园水龙带将其有效载荷作为一股水流从水龙头流向喷嘴。花园水龙头接的水带的容量可能是有限的,但在打水仗的过程中水是源源不断的。只要水从水龙头进入软管,就会一直通过软管然后从喷嘴喷出。同一个花园软管是很容易扩展的,你和朋友们可以玩得更尽兴。
命令式编程就类似打水仗中的水球,本质上没有什么问题,但是拿着类似响应式编程的水管的人在可扩展性和性能方面是有优势的。
Reactor就是上面所说的响应式编程。
Reactive Stream(响应式流)旨在为无阻塞异步流处理提供标准。它通过四个接口来概括:Publisher、Subscriber、Processor、Subscription。
public interface Publisher {
void subscribe(Subscriber super T> subscriber);
}
**注:**响应式编程的核心类型为Mono(不多于一个数据项)、Flux(可表示多个数据项)。
如何实现一个Spring WebFlux实例可以参考。
如何实现一个响应式数据存储实例可以参考。
在介绍什么式微服务之前,先看看之前几十年的开发方式:
你创建一个Web服务的单体应用程序,它构建到一个可部署的 JAR 或 WAR 文件中。开发成单体应用是很正常,几十年来大多数应用程序都是这样构建的。即使将应用程序分解为多模块构建,您最终也仍然会得到一个 JAR 或 WAR 文件,然后再将其推送到生产环境中。
这无疑是构建小型、简单应用程序的最适宜的方法。**但有趣的是,小型应用程序往往会增长。**当需要一个新的特性时,很容易在项目中添加更多的代码。在你意识到大事不妙之前,您的应用就已经变成复杂的单体的应用了。
单体应用看似简单,但存在以下问题:
为了解决单体应用的缺点,微服务出现了:简单来说,微服务架构是将应用程序分解成小规模应用的办法,这些小应用独立开发和部署。这些小应用(微服务)相互协调,以提供更完整和强大的应用程序。
它的优点就是上面单体应用的缺点相对面。
**注:微服务现在还没搞清楚不要紧,**因为它是一个出现没几年的概念,很难用之前的概念来解释、区分它,多看看资料慢慢就理解了。
由于Spring Cloud太多了,只拿出其中Spring Cloud Netflix的Eureka来简单讲讲。
Eureka 这个词表达的含义,是当一个人找到或发现某事时的一种喜悦的感叹。这个含义,使其成为服务注册中心的最合适的命名。微服务正是通过 Eureka 服务发现彼此。
传说 Eureka 是希腊物理学家阿基米德最先表达出来的。当年他坐在浴缸里洗澡时,发现了浮力的原理,便跳了出来,光着身子跑回家,大喊着“Eureka !”
**注:**传说毕竟是传说。
Eureka 充当微服务应用程序中,**所有服务的中心注册表。**Eureka 本身可以被认为是一个微型的服务,其目的是在更大的范围内帮助其他服务发现彼此。
当一个服务实例启动时,它将用自己名称向Eureka注册。如果某个服务有多个实例,他们都以相同的名字在Eureka中注册(相同的名字?)
当另一个服务需要使用某些服务时,它不是通过硬编码(即像函数中写好了参数)的方式去调用服务,而是从Eureka中通过名称去查找服务,而后另一个组件Ribbon会利用负载均衡算法来选择一个合适的服务主机发送给另一个服务。
有关Spring Cloud如何进行配置管理,请跳转配置管理。
有关Spring Cloud如何处理失败和时延,请跳转失败解决。
上面所讲的都是Spring的相关理论和组件,是开发时考虑的东西。
那么如何将一个开发好的项目线上部署呢?比如一个Web项目?
主体流程如下:
详细的操作过程请看:
https://www.jianshu.com/p/3f3c0f5b13f6
https://potoyang.gitbook.io/spring-in-action-v5/