说明
如果你的项目连maven项目都不是,请自行转为maven项目,在按照本教程进行。
本教程适用于spring+springmvc+mybatis+shiro的maven项目。
1.修改pom文件依赖
删除之前的spring依赖,添加springboot依赖
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</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-web</artifactId> <!-- 这个是剔除掉自带的 tomcat部署的--> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!-- tomcat容器部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <!--<scope>compile</scope>--> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- 支持 @ConfigurationProperties 注解 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency> </dependencies>
添加springboot构建插件
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>1.5.9.RELEASE</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins>
添加application启动文件 注意,如果Application在controller,service,dao的上一层包里,无需配置 @ComponentScan,
否则,需要指明要扫描的包。
@SpringBootApplication //@ComponentScan({"com.cms.controller","com.cms.service","com.cms.dao"}) public class Application extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } }
添加springboot配置文件
在resources下面添加application.properties文件
添加基本配置
#默认前缀 server.contextPath=/ # 指定环境 spring.profiles.active=local # jsp配置 spring.mvc.view.prefix=/WEB-INF/jsp/ spring.mvc.view.suffix=.jsp #log配置文件 logging.config=classpath:logback-cms.xml #log路径 logging.path=/Users/mac/work-tommy/cms-springboot/logs/ #数据源 spring.datasource.name=adminDataSource spring.datasource.driverClassName = com.mysql.jdbc.Driver spring.datasource.url = jdbc:mysql://localhost:3306/mycms?useUnicode=true&autoReconnect=true&characterEncoding=utf-8 spring.datasource.username = root spring.datasource.password = 123456
使用@Configuration注入配置
注入mybatis配置,分页插件请自主选择
@Configuration @MapperScan(basePackages = "com.kuwo.dao",sqlSessionTemplateRef = "adminSqlSessionTemplate") public class AdminDataSourceConfig { @Bean(name = "adminDataSource") @ConfigurationProperties(prefix = "spring.datasource") @Primary public DataSource adminDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "adminSqlSessionFactory") @Primary public SqlSessionFactory adminSqlSessionFactory(@Qualifier("adminDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); //分页插件 // PageHelper pageHelper = new PageHelper(); PagePlugin pagePlugin = new PagePlugin(); // Properties props = new Properties(); // props.setProperty("reasonable", "true"); // props.setProperty("supportMethodsArguments", "true"); // props.setProperty("returnPageInfo", "check"); // props.setProperty("params", "count=countSql"); // pageHelper.setProperties(props); //添加插件 bean.setPlugins(new Interceptor[]{pagePlugin}); // 添加mybatis配置文件 bean.setConfigLocation(new DefaultResourceLoader().getResource("classpath:mybatis/mybatis-config.xml")); // 添加mybatis映射文件 bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/system/*.xml")); return bean.getObject(); } @Bean(name = "adminTransactionManager") @Primary public DataSourceTransactionManager adminTransactionManager(@Qualifier("adminDataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "adminSqlSessionTemplate") @Primary public SqlSessionTemplate adminSqlSessionTemplate(@Qualifier("adminSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
添加Interceptor配置,注意addInterceptor的顺序,不要搞乱了
@Configuration public class InterceptorConfiguration extends WebMvcConfigurerAdapter{ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()); } }
添加shiro配置文件
注意:本来使用redis做session缓存,但是和shiro集成发现一个问题,user对象存储以后,从shiro中获取后,无法进行类型转换,所以暂时放弃了redis做session缓存。
@Configuration public class ShiroConfiguration { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.timeout}") private int timeout; @Bean public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } /** * ShiroFilterFactoryBean 处理拦截资源文件问题。 * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,因为在 * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager * Filter Chain定义说明 1、一个URL可以配置多个Filter,使用逗号分隔 2、当设置多个过滤器时,全部验证通过,才视为通过 3、部分过滤器可指定参数,如perms,roles * */ @Bean public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager){ System.out.println("ShiroConfiguration.shirFilter()"); ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); // 必须设置 SecurityManager shiroFilterFactoryBean.setSecurityManager(securityManager); // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 shiroFilterFactoryBean.setLoginUrl("/login_toLogin"); // 登录成功后要跳转的链接 shiroFilterFactoryBean.setSuccessUrl("/usersPage"); //未授权界面; shiroFilterFactoryBean.setUnauthorizedUrl("/403"); //拦截器. Map<String,String> filterChainDefinitionMap = new LinkedHashMap<>(); //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了 filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/login_toLogin", "anon"); filterChainDefinitionMap.put("/login_login", "anon"); filterChainDefinitionMap.put("/static/login/**","anon"); filterChainDefinitionMap.put("/static/js/**","anon"); filterChainDefinitionMap.put("/uploadFiles/uploadImgs/**","anon"); filterChainDefinitionMap.put("/code.do","anon"); filterChainDefinitionMap.put("/font-awesome/**","anon"); //<!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了; //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问--> 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()); return securityManager; } @Bean public ShiroRealm myShiroRealm(){ ShiroRealm myShiroRealm = new ShiroRealm(); // myShiroRealm.setCredentialsMatcher(hashedCredentialsMatcher()); return myShiroRealm; } } /** * 开启shiro aop注解支持. * 使用代理方式;所以需要开启代码支持; * @param securityManager * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager){ AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } /** * 配置shiro redisManager * 使用的是shiro-redis开源插件 * @return */ public RedisManager redisManager() { RedisManager redisManager = new RedisManager(); redisManager.setHost(host); redisManager.setPort(port); redisManager.setExpire(1800); redisManager.setTimeout(timeout); // redisManager.setPassword(password); return redisManager; } /** * cacheManager 缓存 redis实现 * 使用的是shiro-redis开源插件 * @return */ public RedisCacheManager cacheManager() { RedisCacheManager redisCacheManager = new RedisCacheManager(); redisCacheManager.setRedisManager(redisManager()); return redisCacheManager; } /** * RedisSessionDAO shiro sessionDao层的实现 通过redis * 使用的是shiro-redis开源插件 */ @Bean public RedisSessionDAO redisSessionDAO() { RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); redisSessionDAO.setRedisManager(redisManager()); return redisSessionDAO; } @Bean public DefaultWebSessionManager sessionManager() { DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); // sessionManager.setSessionDAO(redisSessionDAO()); return sessionManager; } }