文章目录
前言:
上一章已经把整个框架做了介绍,同时也略带了后续的微服务生态图。这章将从框架的搭建开始说起,spring-boot和spring-cloud对于看这篇文章的jr吗都不陌生,我们就从它们开始。
还是先附上项目结构图:
1.父层目录
是一个空的maven项目,在pom文件中定义spring-boot/clould和其他依赖的版本:spring-boot版本是:2.1.3.RELEASE
spring-cloud:版本是Greenwich.SR2;在父pom中以import的方式申明。
2.FW-BOOT
这个包相当简单,把Spring-boot的相关依赖统一放在这边管理,为什么这么做呢?之前在core包中集成大量的spring-boot包,导致pom文件相当臃肿不好管理;单独拎出来,会让整个pom变得很清晰,后续所有spring-boot的升级,新增依赖都只要在这个maven模块维护即可,很多人会有疑问这样做是不是有点多余,我的观点是,如果我们在这样的细节上做一些小的调整,能为整个框架维护和扩展带来一些好处的话是值得的,这种好处看似没啥,实际上渗透在每个框架开发人员中(自行体会吧)。这个模块不会对外暴露,只会在core中引用。ok,接下啦看下pom文件的引用:引入了spring-boot的相关依赖
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>fw-parent</artifactId>
<groupId>com.mars.fw</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mars.fw</groupId>
<artifactId>FW-BOOT</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--默认的tomcat插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>compile</scope>
</dependency>
<!--默认的tomcat插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--AOP-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--AOP-->
<!--spring默认使用yml中的配置,但有时候要用传统的xml或properties配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--健康监控-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--健康监控-->
<!--自动加载配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!--自动加载配置-->
</dependencies>
</project>
3.FW-ClOUD
这个和FW-BOOT一样把spring-cloud的相关配置依赖抽取出来,在core中引用,目的是一样的;看下pom文件的引用:注意在这里面我引入了spring-cloud-starter-alibaba-nacos-config和spring-cloud-starter-alibaba-nacos-discovery,这是因为服务的注册中心我使用了nacos 而没有使用尤里卡;两种我都使用过,nacos在可视化界面和配置文件管理方面我认为不错,实践下来很刚。nacos的安装部署使用会写专门的章节来介绍使用。
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>fw-parent</artifactId>
<groupId>com.mars.fw</groupId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mars.fw</groupId>
<artifactId>FW-CLOUD</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MARS-FW-CLOUD-STARTER</name>
<developers>
<developer>
<name>dengjinde</name>
<email>dengjinde@vv.cn</email>
</developer>
</developers>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.1.1.RELEASE</version>
</dependency>
</dependencies>
</project>
4.FW-CORE
这个是核心,接下来围绕这个详细来讲解实践过程,没有很复杂难懂的东西。
从上面的目录结构来看:我把core分成了web模块和其他模块。先来讲下web模块:我的定义是所有有关提供API和WEB应用相关的操作都放在这个包中;我们来思考下对于一个web的应用需要具备哪些基础功能(实际上是对springMVC的封装和增强)。
4.1.core-web
1.WebMvcConfigurer的配置
要支持spring-web相关的功能首先要进行web相关的配置,这个大家都清楚了我们新建一个类来实现这个接口进行配置。
这里面主要处理了这么几个问题:
1.前端浏览器ajax的跨域问题
2.静态资源路径设置问题
3.接下来会讲到的统一参数返回的处理就是这个方法:
package com.mars.fw;
import com.mars.fw.web.reponse.handler.MarsRespValueHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.mvc.method.annotation.DeferredResultMethodReturnValueHandler;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
/**
* @Author King
* @Date 2020-04-20
*/
@Configuration
@EnableAspectJAutoProxy
@EnableAutoConfiguration
public class MarsWebMvcConfigure implements WebMvcConfigurer {
/**
* 实例请求映射处理适配器
*/
@Autowired
private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
/**
* 解决跨域问题
* <p>
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge(3600);
}
private CorsConfiguration addcorsConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
List<String> list = new ArrayList<>();
list.add("*");
corsConfiguration.setAllowedOrigins(list);
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source