准备工作:用Eclipse首先安装Spring Boot插件spring tool suite
一、安装完成后开始创建项目,选择Spring Starter Project,点击next
在红框内输入项目名,点击next
选择依赖,点击finish
到这里项目创建完成
二、在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>com.cucycl</groupId>
<artifactId>springbootDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springbootDemo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- redis数据库 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- <dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency> -->
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
<!-- druid阿里巴巴数据库连接池 -->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- shiro权限控制框架 -->
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-spring -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>1.4.0</version>
</dependency>
<!-- 支持shiro标签 -->
<!-- https://mvnrepository.com/artifact/com.github.theborakompanioni/thymeleaf-extras-shiro -->
<dependency>
<groupId>com.github.theborakompanioni</groupId>
<artifactId>thymeleaf-extras-shiro</artifactId>
<version>2.0.0</version>
</dependency>
<!-- shiro+redis缓存插件 -->
<!-- https://mvnrepository.com/artifact/org.crazycake/shiro-redis -->
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis</artifactId>
<version>3.2.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
把一些配置信息写在application.properties文件上
spring.thymeleaf.mode = HTML5
spring.thymeleaf.cache=false
spring.thymeleaf.encoding=UTF-8
# jdbc_config datasource
spring.datasource.url= jdbc:mysql://localhost:3306/xxx?characterEncoding=utf8
spring.datasource.username= xxx
spring.datasource.password= xxx
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.datasource.type= com.alibaba.druid.pool.DruidDataSource
#druid_config
spring.datasource.max-active: 20
spring.datasource.initial-size: 1
spring.datasource.min-idle: 3
spring.datasource.max-wait: 60000
spring.datasource.time-between-eviction-runs-millis: 60000
spring.datasource.min-evictable-idle-time-millis: 300000
spring.datasource.test-while-idle: true
spring.datasource.test-on-borrow: false
spring.datasource.test-on-return: false
spring.datasource.poolPreparedStatements: true
spring.datasource.filters= stat,wall
#redis
spring.redis.host= 127.0.0.1
spring.redis.port= 6379
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.min-idle=0
spring.redis.jedis.pool.max-active= 100
spring.redis.jedis.pool.max-wait= -1
spring.redis.timeout= 5000
# mybatis_config
mybatis.mapper-locations= classpath:com/cucycl/mapper/*Mapper.xml
mybatis.typeAliasesPackage= com.cucycl.entity
编写配置类
1.启动类SpringbootDemoApplication
@MapperScan("com.cucycl.dao")
@SpringBootApplication
@EnableTransactionManagement
@EnableCaching(proxyTargetClass = true) // 开启缓存功能
public class SpringbootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
}
2.DruidDataSourceConfig
package com.cucycl.config;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
@Configuration
public class DruidDataSourceConfig {
@Value("${spring.datasource.url}")
private String url;
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
//初始化时建立物理连接的个数。
@Value("${spring.datasource.initial-size}")
private String initialSize;
//最小连接池数量
@Value("${spring.datasource.min-idle}")
private String minIdle;
//获取连接时最大等待时间,单位毫秒。
@Value("${spring.datasource.max-wait}")
private String maxWait;
//最大连接池数量
@Value("${spring.datasource.max-active}")
private String maxActive;
//Destory线程中如果检测到当前连接的最后活跃时间和当前时间的差值大于minEvictableIdleTimeMillis,则关闭当前连接
@Value("${spring.datasource.min-evictable-idle-time-millis}")
private String minEvictableIdleTimeMillis;
@Bean
public DataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(url);
datasource.setDriverClassName(driverClassName);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setInitialSize(Integer.valueOf(initialSize));
datasource.setMinIdle(Integer.valueOf(minIdle));
datasource.setMaxWait(Long.valueOf(maxWait));
datasource.setMaxActive(Integer.valueOf(maxActive));
datasource.setMinEvictableIdleTimeMillis(
Long.valueOf(minEvictableIdleTimeMillis));
try {
datasource.setFilters("stat,wall");
} catch (SQLException e) {
e.printStackTrace();
}
return datasource;
}
@Bean
public ServletRegistrationBean druidServlet() {
ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean();
servletRegistrationBean.setServlet(new StatViewServlet());
servletRegistrationBean.addUrlMappings("/druid/*");
Map<String, String> initParameters = new HashMap<String, String>();
initParameters.put("resetEnable", "false");// 禁用HTML页面上的“Reset All”功能
initParameters.put("allow", ""); // IP白名单 (没有配置或者为空,则允许所有访问)
servletRegistrationBean.setInitParameters(initParameters);
return servletRegistrationBean;
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
3.MybatisPlusConfig
package com.cucycl.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
@Configuration
@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
4.RedisConfig
package com.cucycl.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
private Logger logger = LoggerFactory.getLogger(RedisConfig.class);
// Redis服务器地址
@Value("${spring.redis.host}")
private String host;
//Redis服务器连接端口
@Value("${spring.redis.port}")
private int port;
// 连接超时时间(毫秒)
@Value("${spring.redis.timeout}")
private int timeout;
//连接池中的最大空闲连接
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
//连接池最大阻塞等待时间(使用负值表示没有限制)
@Value("${spring.redis.jedis.pool.max-wait}")
private long maxWaitMillis;
//连接池中的最小空闲连接
@Value("${spring.redis.jedis.pool.min-idle}")
private int minIdle;
//连接池最大连接数(使用负值表示没有限制)
@Value("${spring.redis.jedis.pool.max-active}")
private int maxActive;
@Bean
public JedisPool redisPoolFactory(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
jedisPoolConfig.setMaxTotal(maxActive);
jedisPoolConfig.setMinIdle(minIdle);
JedisPool jedisPool = new JedisPool(jedisPoolConfig,host,port,timeout,null);
logger.info("JedisPool注入成功!");
logger.info("redis地址:" + host + ":" + port);
return jedisPool;
}
}
5.MyShiroRealm
package com.cucycl.shiro;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
public class MyShiroRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
// TODO Auto-generated method stub
return null;
}
}
6.ShiroConfig
package com.cucycl.config;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.cucycl.shiro.MyShiroRealm;
import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
@Configuration
public class ShiroConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
// 必须设置 SecurityManager
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
shiroFilterFactoryBean.setLoginUrl("/login");
// 登录成功后要跳转的链接
shiroFilterFactoryBean.setSuccessUrl("/index");
// 未授权界面;
shiroFilterFactoryBean.setUnauthorizedUrl("/unAuth");
// 权限控制map.
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
// filterChainDefinitionMap.put("/add", "perms[权限添加]");
// <!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
filterChainDefinitionMap.put("/js/**", "anon");
filterChainDefinitionMap.put("/css/**", "anon");
filterChainDefinitionMap.put("/logout/**", "anon");
filterChainDefinitionMap.put("/**","authc");
shiroFilterFactoryBean
.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 设置realm.
securityManager.setRealm(myShiroRealm());
// 自定义缓存实现 使用redis
securityManager.setCacheManager(cacheManager());
// 自定义session管理 使用redis
securityManager.setSessionManager(sessionManager());
//注入记住我管理器;
securityManager.setRememberMeManager(rememberMeManager());
return securityManager;
}
/**
* 身份认证realm; 自定义
*
* @return
*/
@Bean
public MyShiroRealm myShiroRealm() {
MyShiroRealm myShiroRealm = new MyShiroRealm();
return myShiroRealm;
}
/**
* shiro方言 支持shiro标签
* @return
*/
@Bean
public ShiroDialect shiroDialect() {
return new ShiroDialect();
}
/**
* 配置shiro redisManager
* 使用的是shiro-redis开源插件
* @return
*/
public RedisManager redisManager() {
RedisManager redisManager = new RedisManager();
redisManager.setHost(host+":"+this.port);
redisManager.setTimeout(timeout);
// redisManager.setPassword(password);
return redisManager;
}
/**
* cacheManager 缓存 redis实现
* 使用的是shiro-redis开源插件
* @return
*/
public RedisCacheManager cacheManager() {
RedisCacheManager redisCacheManager = new RedisCacheManager();
redisCacheManager.setRedisManager(redisManager());
redisCacheManager.setExpire(1800);
return redisCacheManager;
}
/**
* RedisSessionDAO shiro sessionDao层的实现 通过redis
* 使用的是shiro-redis开源插件
*/
@Bean
public RedisSessionDAO redisSessionDAO() {
RedisSessionDAO redisSessionDAO = new RedisSessionDAO();
redisSessionDAO.setRedisManager(redisManager());
return redisSessionDAO;
}
/**
* Session Manager
* 使用的是shiro-redis开源插件
*/
@Bean
public DefaultWebSessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
sessionManager.setSessionDAO(redisSessionDAO());
return sessionManager;
}
/**
* cookie对象;
* @return
*/
public SimpleCookie rememberMeCookie(){
//这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//<!-- 记住我cookie生效时间30天 ,单位秒;-->
simpleCookie.setMaxAge(2592000);
return simpleCookie;
}
/**
* cookie管理对象;记住我功能
* @return
*/
public CookieRememberMeManager rememberMeManager(){
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
cookieRememberMeManager.setCipherKey(Base64.decode("5AvVhmFLUs0KTA3Kprsdag=="));
return cookieRememberMeManager;
}
}
三、目录结构
结束收工