Spring Boot学习历程:集成mybatis+freemarker+spring security+ehcache+logback

    以前开发一直用的是Spring MVC,最近有时间就来研究一下Spring Boot。先说一下感受:SpringBoot比较适合快速开发,和SpringMvc比较起来的优点我觉得有:

    1.配置快,启动快。

    2.不需要依赖额外的安装tomcat,只需要几个jar包就能运行。

    3.配置热部署插件,效率更高。

这几天找了好多教程,终于自己搭建出来自己熟悉的一套开发组件,下面会逐渐把代码贴出来。如果不了解spring boot的话可以去百度搜索 springboot入门。

项目的整体结构图:

Spring Boot学习历程:集成mybatis+freemarker+spring security+ehcache+logback_第1张图片

一、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
					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;
	}
	
}

七、配置文件application.properties:
#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

你可能感兴趣的:(SpringBoot)