以前开发一直用的是Spring MVC,最近有时间就来研究一下Spring Boot。先说一下感受:SpringBoot比较适合快速开发,和SpringMvc比较起来的优点我觉得有:
1.配置快,启动快。
2.不需要依赖额外的安装tomcat,只需要几个jar包就能运行。
3.配置热部署插件,效率更高。
这几天找了好多教程,终于自己搭建出来自己熟悉的一套开发组件,下面会逐渐把代码贴出来。如果不了解spring boot的话可以去百度搜索 springboot入门。
项目的整体结构图:
一、jar包
4.0.0
com.oig.spring-boot
spring-boot
0.0.1-SNAPSHOT
UTF-8
1.7
org.springframework.boot
spring-boot-starter-parent
1.3.0.RELEASE
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-devtools
true
true
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-freemarker
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-starter-jdbc
org.mybatis
mybatis-spring
1.3.1
org.mybatis
mybatis
3.4.2
mysql
mysql-connector-java
com.github.pagehelper
pagehelper
4.1.6
tk.mybatis
mapper
3.4.0
javax.persistence
persistence-api
1.0
com.mchange
mchange-commons-java
0.2.11
com.mchange
c3p0
0.9.5.2
net.sf.ehcache
ehcache
commons-net
commons-net
3.6
commons-beanutils
commons-beanutils
1.9.2
commons-logging
commons-logging
org.bouncycastle
bcprov-ext-jdk15on
1.56
org.apache.httpcomponents
httpclient
4.5.1
commons-logging
commons-logging
com.itextpdf
itextpdf
5.5.12
com.google.zxing
core
3.3.0
org.apache.poi
poi
3.10-FINAL
org.apache.poi
poi-ooxml
3.10-FINAL
com.oig.js
nashorn
1.0.1
dom4j
dom4j
1.6.1
commons-codec
commons-codec
1.9
commons-lang
commons-lang
2.6
org.apache.commons
commons-lang3
3.5
commons-io
commons-io
2.5
commons-fileupload
commons-fileupload
1.3.2
com.fasterxml.jackson.module
jackson-module-jaxb-annotations
2.8.7
commons-logging
commons-logging
1.1.1
org.projectlombok
lombok
1.16.18
provided
maven-compiler-plugin
1.6
org.springframework.boot
spring-boot-maven-plugin
repackage
org.springframework
springloaded
1.2.5.RELEASE
org.springframework.boot
spring-boot-maven-plugin
true
spring-boot
二、mybatis配置
1.先是一个mybatis的一个常规配置,数据源改用了c3p0,
package com.oig.application;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class DatasourceConfiguration {
@Bean(name = "dataSource")
@Qualifier(value = "dataSource")
@Primary
@ConfigurationProperties(prefix = "c3p0")
public DataSource dataSource(){
return DataSourceBuilder.create().type(com.mchange.v2.c3p0.ComboPooledDataSource.class).build();
}
//创建SqlSessionFactory
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource());
sqlSessionFactoryBean.setTypeAliasesPackage("com.oig.entity");
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
// sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:mybatis/*.xml"));//指定mapper文件所在目录
sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:com/oig/dao/*.xml"));//指定mapper文件所在目录
sqlSessionFactoryBean.setConfigLocation(resolver.getResource("classpath:mybatis-config.xml"));
// return sqlSessionFactoryBean.getObject();
return sqlSessionFactoryBean;
}
//创建事务管理器
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
2.为mybatis添加了PageHelper组件,所以在上面指定加载了mybatis-config.xml文件,文件位置在src/main/resources下,文件内容如下:
3.配置mybatis通用插件,这是第三方提供的一个开源插件,为mybatis提供了一些通用的增删查改,非常有用。
@Bean
public MapperScannerConfigurer mapperScan(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.oig.dao");
Properties properties = new Properties();
properties.put("style", "normal");
properties.put("mappers", "tk.mybatis.mapper.common.BaseMapper");
// properties.put("mappers", "com.oig.mybatis.mapper.BaseMapper");
mapperScannerConfigurer.setProperties(properties);
return mapperScannerConfigurer;
}
三、logback配置,在src/main/resources下,创建logback-spring.xml,spring boot会自动读取。详细的介绍可以看这篇文章:https://blog.csdn.net/inke88/article/details/75007649
${appname}
%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n
ERROR
DENY
ACCEPT
${logdir}/info.${appname}.log
${logdir}/info.${appname}.%d{yyyy-MM-dd}.log
90
UTF-8
%d [%thread] %-5level %logger{36} %line - %msg%n
Error
${logdir}/error.${appname}.log
${logdir}/error.${appname}.%d{yyyy-MM-dd}.log
90
UTF-8
%d [%thread] %-5level %logger{36} %line - %msg%n
四、spring-security配置,详细介绍可以看这篇文章:https://blog.csdn.net/u012702547/article/details/54319508
package com.oig.application;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import com.oig.security.AuthenticationFaliueHandler;
import com.oig.security.AuthenticationSuccessHandler;
import com.oig.service.impl.UserDetailServiceImpl;
@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
// @Bean
// public DaoAuthenticationProvider daoAuthenticationProvider(){
// DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
// daoAuthenticationProvider.setHideUserNotFoundExceptions(false);
// daoAuthenticationProvider.setUserDetailsService(userDetailsService());
// return daoAuthenticationProvider;
// }
@Bean
public UserDetailServiceImpl userDetailService(){
return new UserDetailServiceImpl();
}
@Bean
public SimpleUrlAuthenticationSuccessHandler authenticationSuccessHandler() {
AuthenticationSuccessHandler authenticationSuccessHandler = new AuthenticationSuccessHandler();
return authenticationSuccessHandler;
}
@Bean
public SimpleUrlAuthenticationFailureHandler authenticationFailureHandler() {
return new AuthenticationFaliueHandler();
}
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.userDetailsService(userDetailService());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().anyRequest().permitAll();
// http.formLogin()
// //设置默认登录成功跳转页面
// .loginPage("/login")
// .successHandler(authenticationSuccessHandler())
// .failureHandler(authenticationFailureHandler())
//// .defaultSuccessUrl("/index")
//// .failureUrl("/login?error=true")
// .permitAll()
// .and()
// //开启cookie保存用户数据
// .rememberMe().rememberMeCookieName("rememberMe")
// //设置cookie有效期
// .tokenValiditySeconds(60 * 60 * 24 * 7)
// //设置cookie的私钥
// .key("wann").useSecureCookie(true)
// .and()
// .logout()
// //默认注销行为为logout,可以通过下面的方式来修改
// .logoutUrl("/logout")
//// //设置注销成功后跳转页面,默认是跳转到登录页面
// .logoutSuccessUrl("/login")
// .invalidateHttpSession(true).clearAuthentication(true).deleteCookies("JSESSIONID","rememberMe")
// .permitAll()
// .and()
// .authorizeRequests()
// .anyRequest().authenticated();
// http
// //http.authorizeRequests()方法有多个子节点,每个macher按照他们的声明顺序执行
// .authorizeRequests()
// //我们指定任何用户都可以访问多个URL的模式。
// //任何用户都可以访问以"/resources/","/signup", 或者 "/about"开头的URL。
// .antMatchers("/resources/**", "/signup", "/about").permitAll()
//
// //以 "/admin/" 开头的URL只能让拥有 "ROLE_ADMIN"角色的用户访问。
// //请注意我们使用 hasRole 方法,没有使用 "ROLE_" 前缀。
// .antMatchers("/admin/**").hasRole("ADMIN")
//
// //任何以"/db/" 开头的URL需要同时具有 "ROLE_ADMIN" 和 "ROLE_DBA"权限的用户才可以访问。
// //和上面一样我们的 hasRole 方法也没有使用 "ROLE_" 前缀。
// .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
//
// //任何以"/db/" 开头的URL只需要拥有 "ROLE_ADMIN" 和 "ROLE_DBA"其中一个权限的用户才可以访问。
// //和上面一样我们的 hasRole 方法也没有使用 "ROLE_" 前缀。
// .antMatchers("/db/**").hasAnyRole("ADMIN", "DBA")
//
// //尚未匹配的任何URL都要求用户进行身份验证
// .anyRequest().authenticated()
// .and()
// // ...
// .formLogin().loginPage("/login").permitAll();
}
@Override
public void configure(WebSecurity web) throws Exception {
super.configure(web);
}
}
五、freemarker配置:
package com.oig.application;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
@Configuration
public class FreemarkerConfigurattion {
@Bean
public CommandLineRunner customFreemarker(final FreeMarkerViewResolver resolver) {
return new CommandLineRunner() {
@Override
public void run(String... args) throws Exception {
//增加视图
resolver.setViewClass(MyFreemarkerView.class);
//添加自定义解析器
// Map map = resolver.getAttributesMap();
}
};
}
}
package com.oig.application;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
public class MyFreemarkerView extends FreeMarkerView{
@Override
protected void exposeHelpers(Map model, HttpServletRequest request) throws Exception {
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort() + path;
model.put("base", basePath);
super.exposeHelpers(model, request);
}
}
六、启动主程序:
package com.oig.application;
import java.util.Properties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import com.fasterxml.jackson.databind.ObjectMapper;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;
@EnableAutoConfiguration
@SpringBootApplication
@ComponentScan(basePackages={"com.oig"})//指定spring要扫描的包
//@ImportResource(locations = {"classpath:applicationContext.xml","classpath:applicationContext-mvc.xml"})
@EnableCaching
//@MapperScan("com.oig.dao")//指定mapper文件所在的包
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
// @Bean
// public ObjectMapper objectMapper(){
// ObjectMapper mapper = new ObjectMapper();
// mapper.findAndRegisterModules();
// return mapper;
// }
@Bean
public MapperScannerConfigurer mapperScan(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.oig.dao");
Properties properties = new Properties();
properties.put("style", "normal");
properties.put("mappers", "tk.mybatis.mapper.common.BaseMapper");
// properties.put("mappers", "com.oig.mybatis.mapper.BaseMapper");
mapperScannerConfigurer.setProperties(properties);
return mapperScannerConfigurer;
}
}
#server
#访问的根路径
server.context-path=/sb
#端口号
server.port=81
#session失效时间
server.session-timeout=30
tomcat.uri-encoding=utf-8
#日志配置
logback.appname=sb
logback.logdir=E\:\\test
spring.profiles.active=dev
spring.http.converters.preferred-json-mapper=gson
spring.jackson.serialization=true
spring.jackson.deserialization=true
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
#datasource
c3p0.jdbcUrl=jdbc:mysql://localhost:3306/数据库?useUnicode=true&characterEncoding=UTF-8
c3p0.user=用户名
c3p0.password=密码
c3p0.driverClass=com.mysql.jdbc.Driver
c3p0.minPoolSize=5
c3p0.maxPoolSize=100
c3p0.maxIdleTime=600
c3p0.acquireIncrement=5
c3p0.maxStatements=1000
c3p0.initialPoolSize=5
c3p0.idleConnectionTestPeriod=60
c3p0.acquireRetryAttempts=30
c3p0.acquireRetryDelay=1000
c3p0.breakAfterAcquireFailure=false
c3p0.testConnectionOnCheckout=false
# FREEMARKER (FreeMarkerAutoConfiguration)
spring.freemarker.allow-request-override=false
spring.freemarker.allow-session-override=false
spring.freemarker.cache=true
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.enabled=true
spring.freemarker.expose-request-attributes=false
spring.freemarker.expose-session-attributes=false
spring.freemarker.expose-spring-macro-helpers=true
spring.freemarker.prefer-file-system-access=true
spring.freemarker.suffix=.ftl
spring.freemarker.template-loader-path=classpath:/templates/
spring.freemarker.settings.template_update_delay=0
spring.freemarker.settings.default_encoding=UTF-8
spring.freemarker.settings.classic_compatible=true
spring.freemarker.order=1
八、遗留问题1:mybatis通用mapper在Spring boot项目中的兼容性有点问题,会报错,解决方法是在src/main/resources下建一个文件 META-INF/spring-devtools.properties,内容如下:
restart.include.companycommonlibs=tk/mybatis.*
九、遗留问题2:在配置完成后遇到一个问题,通过@ResponseBody 返回的内容不是json,而是xml格式。经过百度搜集问题发现,是多了这个jar包,请求的时候会根据header中的accept头信息去返回json还是xml,xml的优先级较高,把下面这个jar去掉就不会了。或者@RequestMapping中produces = MediaType.APPLICATION_JSON_UTF8_VALUE 也能解决,但是不想每个请求都这么写。这个注解是SpringBoot带出来的注解。
com.fasterxml.jackson.dataformat
jackson-dataformat-xml
2.8.7
最后附上源码: https://github.com/li1296883752/sb_test