一:项目Demo生成及全家桶(系列jar包)选择
一:demo生成:
1.在https://start.spring.io/官网进行项目生成(推荐)
2.在编译器中创建相关类型工程,在pom.xml中添加如下依赖,版本建议选择稳定版,最好不要选择最新版.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
二:相关系列jar包选择
1.web相关系列jar包,包括了web开发的系列jar包,如springMVC,spring等
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.内置tomcat系列jar包(直接运行引导类则会运行tomcat)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
PS:父类版本在2.0的时候,tomcat版本为8.5,如下图
3.热部署系列jar包(修改保存后及时自动发布,方便开发及补救紧急bug)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
4.测试类系列jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
5.mybatis系列jar包
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
PS:父类依赖中没有版本号的需要添加版本号,有版本号的可以删除版本号,看版本是否有黄色底线警告即可判断。
6.数据库连接系列jar包,也可使用spring-boot-starter-data-jpa,个人感觉jpa是hibernate的超级加强版,基于持久层方法名生成sql,骚的不行不行的。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
7.前端模板系列jar包,spring boot 默认使用thymeleaf,对比jsp,thymeleaf有非常多的优势,支持html模板,可在网页直接调试样式等,无需像JSP放在应用服务器中加载,相关标签的使用对比JSP略有调整,但区别不是很大。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
PS:如果需要使用JSP,则导入JSP相关jar包即可使用。
<!--配置servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
</dependency> -->
<!--配置jsp jstl的支持-->
<!-- <dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency> -->
<!--对jsp的支持-->
<!-- <dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
8.aop相关jar包,性能监控及相关权限控制等
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
9.缓存相关jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
10.redis数据库相关jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>RELEASE</version>
</dependency>
如需要其他系列的jar包可自行搜索,百度或者spring boot官网都行
二:项目个性化设置及相关配置
一:个性化配置
1.项目运行时的banner图,如下
推荐一个将短语变成各种各样字体的网址:http://www.network-science.de/ascii/
2.配置banner图
在resources下新建一个txt文件即可,也可放置一个banner.gif文件,则项目在加载的时候会将gif每一帧画面变成点状图加载,加载完后开始加载项目,该操作主要是加强团队项目意识。
二:相关配置
1.application文件的配置,不做过多的解释,一看就明白的
#mysql配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/xxxx?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
#redis配置
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.password=test@dbuser2018
spring.redis.ssl=false
# tomcat应用服务器配置
server.port:80
#thymelea模板配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
#mybatis的自定义属性配置 -暂时注释
mybatis.config= classpath:mybatis/sqlmap/mybatis-config.xml
#mybatis的mapper映射集合配置
mybatis.mapperLocations=classpath:mybatis/**/*-sqlmap.xml
#日志打印配置
#打印执行的SQL
logging.level.mapper路径=debug
ps:spring boot会自动加载resources目录下的porperties文件,所以系统配置文件和自定配置文件最好分开。
2.自定义配置文件的相关操作,自定义文件依然放置在resources目录下,需要使用相对应的配置文件类进行读取
3.编写配置文件读取类
/**
* @Title: DBConfig.java
* @Description: 用以获取初始化主键
* @author shadow
* @date 2018年10月9日 下午5:01:58
* @version V1.0
*/
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* @ClassName: DBConfig
* @Description: 表名主键配置类,用以获取初始化主键
* @author shadow
* @date 2018年10月9日 下午5:01:58
*/
@Component
@ConfigurationProperties(prefix="dbid")
@PropertySource("classpath:dbidconfig.properties")
public class DBIdConfig {
//单位配置主键
private String configCompanyId;
public String getConfigCompanyId() {
return configCompanyId;
}
public void setConfigCompanyId(String configCompanyId) {
this.configCompanyId = configCompanyId;
}
}
4.获取方式,直接像获取实体类属性一样get就行了。
三:项目业务相关基础类编写
一:权限方面,spring boot 推荐的spring security ,因为不是非常熟悉security,所以使用shiro
导入jar包,以下含有thymeleaf模板对shiro标签的支持。
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
</dependency>
<!--thymeleaf-shiro-extras-->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
shiro重要的两个类:一个是bean配置类,一个是重写AuthorizingRealm的权限验证和授权的自定义类
1.配置类
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import java.util.LinkedHashMap;
import java.util.Map;
@Configuration
public class ShiroConfig {
/**
* 缓存管理器
* @return
*/
@Bean
public EhCacheManager ehCacheManager(){
EhCacheManager cacheManager = new EhCacheManager();
cacheManager.setCacheManagerConfigFile("classpath:encache/ehcache-shiro.xml");
return cacheManager;
}
/**
*
* @Title: shirFilter
* @Description: shiro核心拦截器
* @param @param securityManager
* @param @return 设定文件
* @return ShiroFilterFactoryBean 返回类型
* @throws
*/
@Bean
public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
//拦截器.authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问
Map<String,String> filterChainDefinitionMap = new LinkedHashMap<String,String>();
// 配置不会被拦截的链接 顺序判断
//静态资源
filterChainDefinitionMap.put("/static/**", "anon");
//注册路径
filterChainDefinitionMap.put("/registration", "anon");
//登录校验
filterChainDefinitionMap.put("/loginCheck", "anon");
//配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
filterChainDefinitionMap.put("/logout", "logout");
//所有url都必须认证通过才可以访问
filterChainDefinitionMap.put("/**", "authc");
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
//未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
*
* @Title: shiroDialect
* @Description: 用于thymeleaf模板使用shiro标签
* @param @return 设定文件
* @return ShiroDialect 返回类型
* @throws
*/
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
/**
*
* @Title: hashedCredentialsMatcher
* @Description: 登录认证加密方式,需和数据库加密方式一致,密文=(盐+明文)MD5
* @param @return 设定文件
* @return HashedCredentialsMatcher 返回类型
* @throws
*/
@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher(){
HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法;
return hashedCredentialsMatcher;
}
/**
*
* @Title: securityManager
* @Description: 权限认证信息,设置Realm
* @param @return 设定文件
* @return SecurityManager 返回类型
* @throws
*/
@Bean
public SecurityManager securityManager(){
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(campShiroRealm());
securityManager.setCacheManager(ehCacheManager());
return securityManager;
}
/**
*
* @Title: campShiroRealm
* @Description: 配置shiro仓库
* @param @return 设定文件
* @return CampShiroRealm 返回类型
* @throws
*/
@Bean
public CampShiroRealm campShiroRealm(){
CampShiroRealm myShiroRealm = new CampShiroRealm();
myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
return myShiroRealm;
}
/**
*
* @Title: advisorAutoProxyCreator
* @Description: 开启shiro aop注解支持,使用代理方式;所以需要开启代码支持
* @param @return 设定文件
* @return DefaultAdvisorAutoProxyCreator 返回类型
* @throws
*/
@Bean
public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
/**
*
* @Title: authorizationAttributeSourceAdvisor
* @Description: 开启shiro aop注解支持,使用代理方式;所以需要开启代码支持
* @param @param securityManager
* @param @return 设定文件
* @return AuthorizationAttributeSourceAdvisor 返回类型
* @throws
*/
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){
AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
return authorizationAttributeSourceAdvisor;
}
}
2.自定义类:
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import com.facejoy.camp.core.commons.WordDefined;
import com.facejoy.camp.entity.sys.SysAuth;
import com.facejoy.camp.entity.sys.SysRole;
import com.facejoy.camp.entity.sys.SysUser;
import com.facejoy.camp.service.sys.SysUserService;
public class CampShiroRealm extends AuthorizingRealm {
@Autowired
@Lazy
SysUserService sysUserService;
//权限管理,存入权限
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
ShiroUser shiroUser = (ShiroUser)principals.getPrimaryPrincipal();
if (shiroUser == null) {
return null;
} else {
SysUser user = sysUserService.getUserRoleAndAuth(shiroUser.getLoginName());
if (user != null) {
//System.out.println("用户角色:" + user.getRoles());
for (SysRole role : user.getRoles()) {
authorizationInfo.addRole(role.getRoleCode());
}
//System.out.println("用户权限:" + user.getAuths());
for (SysAuth auth : user.getAuths()) {
authorizationInfo.addStringPermission(auth.getAuthCode());
}
}
}
return authorizationInfo;
}
//登录认证,存入用户信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usertoken = (UsernamePasswordToken)token;
SysUser sysUser = sysUserService.findUserByLoginName(usertoken.getUsername());
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
new ShiroUser(sysUser.getUserId(), sysUser.getLoginName(), sysUser.getUserName()),
sysUser.getLoginPwd(),
ByteSource.Util.bytes(WordDefined.ADD_PWD_FIELD),
getName()
);
return authenticationInfo;
}
}
3.shiro权限缓存配置文件ehcache-shiro.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<diskStore path="java.io.tmpdir"/>
<!--
name:缓存名称。
maxElementsInMemory:缓存最大数目
maxElementsOnDisk:硬盘最大缓存个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
overflowToDisk:是否保存到磁盘,当系统当机时
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
memoryStoreEvictionPolicy:
Ehcache的三种清空策略;
FIFO,first in first out,这个是大家最熟的,先进先出。
LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
<!-- 登录记录缓存锁定10分钟 -->
<cache name="passwordRetryCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="0"
overflowToDisk="false"
statistics="true">
</cache>
</ehcache>
4.tomcat错误返回自定义类
@Component
public class ErrorPageConfig implements ErrorPageRegistrar{
@Override
public void registerErrorPages(ErrorPageRegistry registry) {
//1、按错误的类型显示错误的网页
//错误类型为404,找不到网页的,默认显示404.html网页
ErrorPage e404 = new ErrorPage(HttpStatus.NOT_FOUND, "/static/error/404.html");
//错误类型为500,表示服务器响应错误,默认显示500.html网页
ErrorPage e500 = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/static/error/500.html");
registry.addErrorPages(e404, e500);
}
}
5.缓存标签的使用,可缓存查询结果,对应有删除缓存标签,不一一举例
在引导类上加上@EnableCaching标签
至此:基本框架搭建完成,可以搭建业务结构了。
spring boot 非常适合微服务,只有几个接口或者业务比较少的项目,纯接口可生成jar包文件直接在服务器上运行,含有业务和页面的可生成war包直接发布。
6.thymeleaf模板中shiro标签的使用和jsp没有较大区别,引入thymeleaf使用标签即可,thymeleaf具体使用方法不赘述,可查看相关手册。
<html lang="zh_CN" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org"
xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">