SSO是公司一个已经存在了若干年的项目,后端采用SpringMVC、MyBatis,数据库使用MySQL,前端展示使用Freemark。今年,我们对该项目进行了一次革命性的改进,改造成SpringCloud架构,并且把前后端分离,前端采用Vue框架。
一、使用SpringCloud架构进行改造
1.1 为什么使用SpringCloud
SpringCloud的核心是SpringBoot,相比较于传统的Spring,SpringCloud具有以下优点:
- 部署简单,SpringBoot内置了Tomcat容器,可以将程序直接编译成一个jar,通过java-jar来运行。
- 编码简单,SpringBoot只需要在pom文件中添加一个starter-web依赖,即可帮助开发者快速启动一个web容器,非常方便。
- 配置简单,SpringBoot可以通过简单的注解方式来代替原先Spring非常复杂的xml方式。如果我想把一个普通的类交给Spring管理,只需要添加@Configuration和@Bean两个注解即可。
- 监控简单,我们可以引入spring-boot-start-actuator依赖,直接使用REST方式来获取进程的运行期性能参数,从而达到监控的目的。
1.2 一个常规项目都需要改造哪些部分
1.2.1 配置文件
SSO项目改造前充斥着大量的配置文件,主要包含以下这些部分:
- 静态资源相关
- 数据源
- mybatis配置
- redis配置
- 事务
- 拦截器拦截内容
- 监听器、过滤器
- 组件扫描路径配置
本文着重介绍以下几个部分:
1)静态资源处理
SpringMVC中,如果mvc:interceptors配置的URL规则如下,则不会拦截静态资源。
但是如果配置的是:
方案1: 在web.xml中配置default,用defaultServlet先处理请求如:
default*.jpgdefault*.pngdefault*.gifdefault*.icodefault*.gifdefault*.jsdefault*.css
方案2:使用标签声明静态资源路径
方案3:使用mvc:default-servlet-handler/标签
SpringBoot解决方案:继承WebMvcConfigurerAdapter实现addResourceHandlers方法。
public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**") .addResourceLocations("classpath:/resource/")//sso静态资源 .addResourceLocations("classpath:/META-INF/resources/")//swagger静态资源 .setCachePeriod(0);//0表示不缓存 }
sso静态资源文件路径如图:
![718fba264188810a3961c07de7cf59e3.png](https://i-blog.csdnimg.cn/blog_migrate/c135bf0cae76623cd05d42fe960245fe.jpeg)
2)拦截器
SpringMVC配置文件内容:
拦截任何请求并且初始化参数,有些请求是不需要拦截的,有的请求登录后不需要经过权限校验直接放行。
请求地址请求地址
SpringBoot中添加拦截器只需继承WebMvcConfigurerAdapter,并重写addInterceptors方法即可。
/*** 拦截器 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(permissionInterceptor). addPathPatterns("/**"); super.addInterceptors(registry); }
自定义的拦截器需要初始化一些参数,因此需要在注册拦截器之前注册,这里我们设置为懒加载。免登录拦截的路径,以及登录后不需要判断权限的路径都写在yml文件了,通过系统环境变量Environment获取值。
@Autowired@Lazy private PermissionInterceptor permissionInterceptor; @Autowired private Environment environment;/****/@Bean public PermissionInterceptor permissionInterceptor() { PermissionInterceptor permissionInterceptor = new PermissionInterceptor(); List excludeUrls = Arrays.asList(environment.getProperty("intercept.exclude.path").split(