Spring生态圈的演进从未停歇。自从2013年SpringBoot出现以来,基于Spring的应用构建方式已经逐渐发生变化。
Spring无疑是JEE发展历程中最成功的开发平台之一,但这并不能阻止大家的吐槽。在早期版本中,开发人员需要配置大量的XML---这在引入注解方式后有所改善,另外还要处理复杂的(版本)依赖关系,一点差池都可能导致系统无法正常运行。SpringBoot解决了上述问题,同时带来了全新的开发体验,为RAD领域提供了一种优秀的解决方案。
本文将尝试整合一些主流的框架,基于SpringBoot搭建出适合某类场景的应用架构,提供特定的技术选型参考。
1、入门级应用
可认为包含前端、中端和后端。前端部分使用官方推荐的thymeleaf模板进行渲染,中端部分就是基于SpringBoot的微服务应用。至于后端,可以是其它服务或者是数据库系统,此处以mysql为例。以下将适当详细地描述一个轻服务通常包含哪些东西。
以maven作为构建工具,创建一个项目。pom.xml配置如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.j1ee</groupId> <artifactId>testing</artifactId> <version>1.0</version> <packaging>jar</packaging> <name>testing</name> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.3.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>springloaded</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
持久层组件选用jpa而不是Mybatis,数据库连接池组件采用HikariCP。应用需要一些必要的配置,如/src/main/resources/application.properties所示的一些信息:
#server server.port=8081 server.session-timeout=20 server.context-path=/testing server.tomcat.uri-encoding=UTF-8 #datasource spring.datasource.url=jdbc:mysql://192.168.124.7:3306/test?useUnicode=true&characterEncoding=utf8 spring.datasource.username=mysqlx spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.max-idle=100 spring.datasource.max-wait=10000 spring.datasource.min-idle=10 spring.datasource.initial-size=10 spring.datasource.type=com.zaxxer.hikari.HikariDataSource #jpa spring.jpa.database = MYSQL spring.jpa.show-sql = true spring.jpa.hibernate.ddl-auto=none spring.jpa.generate-ddl=true spring.jpa.properties.hibernate.show_sql=true
创建启动类,该类的目录是有要求的,需要放在根包下。该类所在的main方法是应用的入口,将系统引导工作交给了SpringBoot。
@SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
以一次请求为例,首先有一个实体bean:
@Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private long id; @NotNull private String name; @NotNull private int age; //… }
有一个Data Access Object:
@Repository public interface UserRepository extends JpaRepository<User, Long> { public User findByName(String name); }
有一个前端展示需要的模板/src/main/resources/templates/user.html:
<h3>user info:</h3> <div> name: <span th:text="${user.name}">not find the user</span><br/> age: <span th:text="${user.age}">no age</span><br/> </div>
再有一个UserService和UserServiceImpl,作为逻辑层,此处略过;
最后还需要一个Controller:
@Controller public class UserController { @Autowired UserService userService; @RequestMapping("/user/{name}") public String getByName(@PathVariable String name, Model model) { User user = userService.findByName(name); model.addAttribute("user", user); return "user"; } }
这样一个MVC模块的雏形就有了。通过mvn spring-boot:run启动应用,在浏览器中输入http://localhost:8081/testing/user/du访问,出现如下结果:
user info: name: du age: 18
Boot提供了一些特性,比如嵌入式应用服务容器(默认tomcat)。Maven可将应用打包成一个fat jar,在服务器上直接用java运行即可启动程序。
Boot基于约定优于配置的原则,做了很多自动化配置的工作。如前所述,这些(默认)配置是可以根据需要修改的,也可以通过启动命令参数传入,后一种方式在云端部署时比较有用。
入门级SpringBoot应用的技术架构如下:
2、HA/负载均衡
一些重要的系统需要支持ha,有一定并发规模的情况下还需要做负载均衡,这看起来和SpringBoot没有太大的关系。实际上并非如此,Boot支持开箱即用的特性,使得部署前所未有的方便了。由于Boot对配置支持的优先级划分能力,允许在应用之外传入参数的方式运行,进一步提高了其实用性。
对于规模较大的系统,如何提高吞吐量,解决IO瓶颈一直是关注的焦点。传统的方法是分库(垂直)分表(水平),这在很多时候需要做不少额外的工作,并且会带来各种问题。为解决该问题,实现数据库集群负载和数据安全,Oracle提供了RAC方案,后来出现了支持多种数据库的工具 MyCat。
MongoDB在很多时候是一个更好的选择,它支持三种集群方式,可根据实际情况使用。Boot可以很方便的集成包括MongoDB在内的大部分数据库系统,只需要引入必要的starter组件(还需要配置一些数据连接相关的参数,略)。:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
本部分不涉及DNS和CDN,它们也是负载均衡的常用技术。
以LVS软交换为例,SpringBoot集群部署示图如下:
3、内容性应用
另外一些情况则需要一些变化。对于内容性比较强的系统,比如微博、论坛之类的,需要对大量的内容进行缓存处理,以减少不必要的IO操作,提高响应速度。这些内容通常实时性要求不高,只需保持最终一致性即可。目前流行的方案是redis,实际上mongodb也是可以满足要求的。
引入依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency>
可能的方式:
对于海量数据,需要进行数据分析的话,考虑引入hadoop/spark替换当前的持久化存储。
4、高并发系统
某些极端情况需要特殊处理。本人曾尝试过一些量化交易的研究,就以股票行情为例简单地介绍一下。假如需要做一个Http服务,为用户提供股票行情信息,并且这个东西访问量非常大。那该如何搞呢?
除了做负载之外,关键的一点就是减少损耗:减少IO、减少计算、减少转换,最好一个请求上来服务端马上就能把需要的行情数据直接返回。所以,问题的关键就是这个数据了。可能的过程是这样的:原始数据经过清洗、处理后推送到某一数据源,专用工具从数据源获取需要的数据推到服务端(如果可以,不经过数据源直接推送到服务端显然会更快),服务端缓存这些数据并响应客户端请求。很明显,数据处理和推送过程会导致行情有一点儿延迟,需要把这个延迟尽可能做小。这样,一次数据处理就可以应付N多次请求了,这个N基本上就要看服务器性能和网络情况了。
如图所示,采用EhCache作为微服务Service的服务端缓存组件,搭建集群环境。其中,虚线部分标识出一个EhCache集群,它连接了两个服务:Service和Helper。Helper服务负责获取数据(被动或主动)并写入缓存,EhCache会将这些数据广播到其它节点完成同步。Service应用只需要进行读操作即可,最大限度地降低了IO频次和重复计算。
不难发现,SpringBoot很容易地与当前的一些主流框架进行整合,适合很多应用场景的开发。Spring框架经过若干年的发展,集其大成者看来是Boot了。当然,它不仅仅是某一技术或某一工具,我们应更多地关注其背后体现的思想,掌握解决问题的方法。
相关推荐
2,使编码变得简单,SpringBoot采用 JavaConfig的方式对Spring进行配置,并且提供了大量的注解,极大的提高了工作效率,比如@Configuration和@bean注解结合,基于@Configuration完成类扫描,基于@bean注解把返回值...
### 基于SpringBoot的免税商品优选购物商城系统关键知识点解析 #### 一、课题背景与意义 ##### 1.1 课题开发背景 随着电子商务的快速发展,越来越多的消费者倾向于在线购物。免税商品因其价格优势吸引了大量消费...
Spring Boot提供了一个快速构建独立、生产级别的Spring应用程序的方法,无需大量的配置代码。 2. **B/S架构**:该系统采用了浏览器/服务器(Browser/Server, B/S)架构模式,这使得用户只需通过浏览器即可访问系统,...
3. **Web**:Spring的Web模块提供了用于构建Web应用程序的工具,如Spring MVC,这是一个模型-视图-控制器架构,简化了Web应用程序的开发。此外,Spring Web Services模块支持创建基于SOAP和RESTful的Web服务。 4. *...
SpringBoot 是一个基于 Spring 框架的快速开发工具,旨在简化 Spring 应用程序的初始设置和常规配置。它遵循“约定优于配置”的原则,让开发者能够更快地启动和运行项目,而无需进行大量的手动配置。 1.1 ...
后端基于Springboot,可以将运行类作为入口运行在内置的Web容器中。 10. 数据库MySQL:MySQL是一种流行的开源关系型数据库管理系统(RDBMS),以它的高性能、可靠性、易用性以及对多种平台的支持而闻名。在本OA办公...
接下来,SpringBoot是Spring框架的一个子项目,它简化了基于Spring的应用程序的初始搭建以及开发过程。SpringBoot以其“开箱即用”的特性受到开发者的喜爱,无需大量的配置即可创建独立的、生产级别的Java应用。在...
使用SpringBoot 2,Spring JPA,Spring Security,Thymeleaf,jQuery,Bootstrap 4和FontsAwesome构建的简单发票管理系统。 演示版 您可以在用户名admin中访问此Web应用程序的实时演示。 密码:12345 屏幕截图 运行 ...
- **创建Maven项目**:作为基础,项目需基于Maven构建,导入Spring Boot的父工程依赖,简化项目构建配置。 - **POM.xml配置**:在pom.xml中添加Spring Boot的起步依赖,以便利用其提供的默认配置和自动配置功能。 ...
Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了一种类型安全的可重构配置方式,可以代替XML。 2. 项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,...
Spring Boot 是一种快速构建和管理基于Spring的应用程序的框架,它极大地简化了Spring应用程序的配置和开发过程。在本文中,我们将深入探讨Spring Boot的基础知识,从环境配置到Hello World应用的创建,以及JPA的...
在Spring框架中,JNDI(Java Naming and Directory Interface)主要用来查找和绑定资源,如数据源、EJB等。JNDI允许我们通过名称来访问分布式环境...理解这一过程将帮助你更好地构建和维护基于Spring的分布式应用程序。
在这个配置中,Restlet的版本是restlet-jee-2.0.3,这是针对Java EE环境的版本。同时,Spring框架的版本为3.0.4.RELEASE。这些依赖需要添加到你的项目构建配置(如Maven或Gradle)中,以便正确地引入和管理库。 接...