------看完了《Spring In Action》,對于spring提供的Java配置有自己一定的了解,它能讓你更好的了解運作機制。至于方不友善,見人見智。
目錄結構如下圖
------entity用于存放實體類,model用于存放一些業務pojo
pom.xml
------不止于ssm、redis和thymeleaf的依賴,還有諸如druid、fastjson、flyway(資料庫版本管理工具)依賴
<properties>
<webVersion>3.1</webVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<javaee-api.version>7.0</javaee-api.version>
<jstl.version>1.2.2</jstl.version>
<junit.version>4.11</junit.version>
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<thymeleaf.layout.version>1.2.3</thymeleaf.layout.version>
<spring.version>4.3.18.RELEASE</spring.version>
<mybatis.version>3.2.1</mybatis.version>
<mybatis.spring.version>1.2.0</mybatis.spring.version>
<mybatis.generator.version>1.3.5</mybatis.generator.version>
<mysql.version>8.0.12</mysql.version>
<alibaba.druid.version>1.0.16</alibaba.druid.version>
<flyway.version>4.0.3</flyway.version>
<slf4j.version>1.7.7</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<logback.version>1.1.2</logback.version>
<logback.spring.version>0.1.1</logback.spring.version>
<alibaba.fastjson.version>1.2.31</alibaba.fastjson.version>
<jackson.version>2.8.7</jackson.version>
<redis.jedis.version>2.9.0</redis.jedis.version>
<spring.data.redis>1.8.0.RELEASE</spring.data.redis>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>${javaee-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- jstl依賴 -->
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.servlet.jsp.jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!-- junit依賴 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- thymeleaf依賴 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
<!-- thymeleaf布局依賴 -->
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>${thymeleaf.layout.version}</version>
</dependency>
<!-- 添加spring依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring單元測試依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<!-- springmvc依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- mybatis依賴 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- mybatis/spring依賴-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<!-- MyBatis逆向工程 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>${mybatis.generator.version}</version>
</dependency>
<!-- mysql驅動依賴 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- druid datasource依賴 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${alibaba.druid.version}</version>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>${flyway.version}</version>
</dependency>
<!-- fastjson依賴 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${alibaba.fastjson.version}</version>
</dependency>
<!-- logback依賴 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.logback-extensions</groupId>
<artifactId>logback-ext-spring</artifactId>
<version>${logback.spring.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${redis.jedis.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>${spring.data.redis}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
Config類
TinyHelpWebAppInitializer.java
-------Servlert3.0後規範允許取消web.xml配置,可以隻使用注解。在Servlet3.0環境中,容器會在classpath下查找實作了ServletContainerInitializer接口的類,如果能發現了,就會用它來配置Servlet容器。Spring提供了接口的實作類SpringServletContainerInitializer,這個類又會查找實作了WebApplicationInitializer接口的類并将配置任務交給它們完成,WebApplicationInitializer與實作類關系如下圖:
package com.tinyhelp.config;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class TinyHelpWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
// 設定檔案上傳配置
// 存儲檔案的臨時位置
private static final String LOCATION = "/temp";
// 最大檔案大小,5MB
private static final long MAX_FILE_SIZE = 5242880;
// 最大請求大小,20MB
private static final long MAX_REQUEST_SIZE = 20971520;
// 如果檔案大小達到了一個指定的最大容量,将會寫入臨時檔案。預設0,上傳的檔案都寫入磁盤上。
private static final int FILE_SIZE_THRESHOLD = 0;
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{ RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{ WebConfig.class };
}
//将DispatcherServlet映射到“/”
@Override
protected String[] getServletMappings() {
return new String[]{ "/" };
}
@Override
protected void customizeRegistration(Dynamic registration) {
//配置檔案上傳
registration.setMultipartConfig(new MultipartConfigElement(LOCATION,MAX_FILE_SIZE,MAX_REQUEST_SIZE,FILE_SIZE_THRESHOLD));
}
}
WebConfig.java
-------這個類主要是用來配置Web元件的Bean,如控制器。Spring5後,WebMvcConfigurerAdapter已被廢棄,官方推薦實作WebMvcConfigurer接口。
[email protected](basePackageClasses = { BasePackageWeb.class }),元件掃描選擇掃描一個空接口類,它放在放Controller和Servlet的Web包裡,這樣spring就會掃描到它和它的同級包與子包。接下的配置遵從這樣的規則,因為掃描一個String類型不安全,掃描接口的話,能便于重構等。
package com.tinyhelp.config;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.thymeleaf.spring4.ISpringTemplateEngine;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.tinyhelp.web.BasePackageWeb;
@Configuration
@EnableWebMvc
@ComponentScan(basePackageClasses = { BasePackageWeb.class })
@Import({ThymeleafConfig.class, MultipartResolverConfig.class})
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {
// TODO Auto-generated method stub
}
@Override
public void addCorsMappings(CorsRegistry arg0) {
// TODO Auto-generated method stub
}
@Override
public void addFormatters(FormatterRegistry arg0) {
// TODO Auto-generated method stub
}
@Override
public void addInterceptors(InterceptorRegistry arg0) {
// TODO Auto-generated method stub
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//增加資源控制器,并設定資源映射路徑和資源路徑,通路WEB-INF下的靜态資源
registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/static/");
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> arg0) {
// TODO Auto-generated method stub
}
@Override
public void addViewControllers(ViewControllerRegistry arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
//開啟靜态資源的預設處理器
configurer.enable();
}
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//隻配置fastjson消息轉換器
FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
//配置資訊
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setCharset(Charset.forName("UTF-8"));
fastJsonConfig.setDateFormat("yyyy-MM-dd hh:mm:ss");
fastJsonConverter.setFastJsonConfig(fastJsonConfig);
//設定支援的Media類型轉換
ArrayList<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.TEXT_PLAIN);
mediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
fastJsonConverter.setSupportedMediaTypes(mediaTypes);
//添加fastjsonConverter到Converters
converters.add(fastJsonConverter);
}
@Override
public void configurePathMatch(PathMatchConfigurer arg0) {
// TODO Auto-generated method stub
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
// TODO Auto-generated method stub
}
public ISpringTemplateEngine templateEngine() {
// TODO Auto-generated method stub
return null;
}
@Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
// TODO Auto-generated method stub
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> arg0) {
// TODO Auto-generated method stub
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
// TODO Auto-generated method stub
return null;
}
@Override
public Validator getValidator() {
// TODO Auto-generated method stub
return null;
}
}
ThymeleafConfig.java
-------這個類是用來配置模闆解釋器、模闆引擎和thymeleaf視圖解釋器。
package com.tinyhelp.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ITemplateResolver;
@Configuration
public class ThymeleafConfig {
//模闆解釋器
@Bean
public ITemplateResolver templateResolver(){
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode(TemplateMode.HTML);
//解決中文亂碼
templateResolver.setCharacterEncoding("UTF-8");
//開發環境關閉緩存便于調試,生産環境采用緩存
templateResolver.setCacheable(false);
return templateResolver;
}
//模闆引擎
@Bean
public TemplateEngine templateEngine(ITemplateResolver templateResolver){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
//thymeleaf視圖解釋器
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
//解決中文亂碼
viewResolver.setCharacterEncoding("UTF-8");
return viewResolver;
}
}
MultipartResolverConfig.java
-------這個類是用來配置配置檔案上傳解釋器的。沒有用CommonsMultipartResolver,因為依賴于第三方實作。能依賴于Servlet本身是最好的了。
package com.tinyhelp.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
@Configuration
public class MultipartResolverConfig {
//配置依賴Servlet3.0對multipart請求的支援
@Bean
public MultipartResolver multipartResolver(){
return new StandardServletMultipartResolver();
}
}
RootConfig.java
--------這個類主要是用來配置除Web元件的Bean外其它的配置Bean,如資料源等。
package com.tinyhelp.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import com.tinyhelp.entity.BasePackageEntity;
import com.tinyhelp.service.impl.BasePackageServiceImpl;
@Configuration
@ComponentScan(basePackageClasses = { BasePackageServiceImpl.class, BasePackageEntity.class })
@Import({DataBaseConfig.class, RedisConfig.class})
public class RootConfig {
}
DataBaseConfig.java
--------這個類主要是用來配置druid資料源、mybatis和事務管理器的。事務使用注解事務,使用時在業務類或方法上加@Transaction注解。
--------其中注釋的代碼是關于flyway的。如果要應用啟動的時候實作資料庫遷移,将注釋代碼打開即好。如果不需要啟動的時候實作資料庫遷移,樓主選擇了另一種方法,使用flyway的maven插件。
package com.tinyhelp.config;
import java.io.IOException;
import java.util.ArrayList;
import javax.sql.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.logging.Log4jFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallFilter;
import com.tinyhelp.dao.BasePackageDao;
@Configuration
@PropertySource("classpath:/jdbc.properties")
@MapperScan(basePackageClasses = { BasePackageDao.class } )
@EnableTransactionManagement
public class DataBaseConfig {
private String driverClassName;
private String url;
private String username;
private String password;
private int initialSize;
private int minIdle;
private int maxActive;
private int maxWait;
private int timeBetweenEvictionRunsMillis;
private int minEvictableIdleTimeMillis;
private String validationQuery;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private boolean poolPreparedStatements;
private int maxPoolPreparedStatementPerConnectionSize;
private String connectionProperties;
@Value("${spring.datasource.driverClassName}")
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
@Value("${spring.datasource.url}")
public void setUrl(String url) {
this.url = url;
}
@Value("${spring.datasource.username}")
public void setUsername(String username) {
this.username = username;
}
@Value("${spring.datasource.password}")
public void setPassword(String password) {
this.password = password;
}
@Value("${spring.datasource.initialSize}")
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
@Value("${spring.datasource.minIdle}")
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
@Value("${spring.datasource.maxActive}")
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
@Value("${spring.datasource.maxWait}")
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
@Value("${spring.datasource.minEvictableIdleTimeMillis}")
public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
@Value("${spring.datasource.validationQuery}")
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
@Value("${spring.datasource.testWhileIdle}")
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
@Value("${spring.datasource.testOnBorrow}")
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
@Value("${spring.datasource.testOnReturn}")
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
@Value("${spring.datasource.poolPreparedStatements}")
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}
@Value("${spring.datasource.connectionProperties}")
public void setConnectionProperties(String connectionProperties) {
this.connectionProperties = connectionProperties;
}
//配置flyway資料庫初始化,在項目啟動時遷移資料庫
/*@Bean(initMethod="migrate")
public Flyway flyway() {
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource());
flyway.setEncoding("UTF-8");
//sql存放位置
flyway.setLocations("db/migration");
flyway.setBaselineOnMigrate(true);
flyway.setPlaceholderReplacement(false);
//設定開始的版本
flyway.setBaselineVersion(MigrationVersion.fromVersion("1"));
return flyway;
}*/
//druid監控配置
@Bean
public StatFilter statFilter() {
return new StatFilter();
}
//druid防火牆配置
@Bean
public WallFilter wallFilter() {
WallFilter wallFilter = new WallFilter();
//放行flyway配置
/*WallConfig wallConfig = new WallConfig();
wallConfig.setVariantCheck(false);
wallConfig.setNoneBaseStatementAllow(true);
wallConfig.setCommentAllow(true);
wallConfig.setMultiStatementAllow(true);
wallFilter.setConfig(wallConfig);*/
return wallFilter;
}
//druid日志配置
@Bean
public Log4jFilter log4jFilter() {
return new Log4jFilter();
}
//druid連接配接池配置
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setInitialSize(initialSize);
dataSource.setMinIdle(minIdle);
dataSource.setMaxActive(maxActive);
dataSource.setMaxWait(maxWait);
dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
dataSource.setValidationQuery(validationQuery);
dataSource.setTestWhileIdle(testWhileIdle);
dataSource.setTestOnBorrow(testOnBorrow);
dataSource.setTestOnReturn(testOnReturn);
dataSource.setPoolPreparedStatements(poolPreparedStatements);
dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
//代理stat,wall,log4j
ArrayList<Filter> filterList = new ArrayList<>();
filterList.add(statFilter());
filterList.add(wallFilter());
filterList.add(log4jFilter());
dataSource.setProxyFilters(filterList);
dataSource.setConnectionProperties(connectionProperties);
return dataSource;
}
//mybatis配置
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException{
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
//設定連接配接池
sqlSessionFactoryBean.setDataSource(dataSource());
//設定映射檔案位置
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mappers/*.xml"));
//别名,讓*Mapper.xml實體類映射可以不加上具體包名
sqlSessionFactoryBean.setTypeAliasesPackage("com.tinyhelp.model");
return sqlSessionFactoryBean;
}
//配置事務管理器
@Bean(name = "transactionManager")
public DataSourceTransactionManager dataSourceTransactionManager(){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource());
return dataSourceTransactionManager;
}
}
jdbc.properties
--------url,username,password,修改成自己的
#連接配接池基本資訊
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
#連接配接池配置
spring.datasource.initialSize=5
spring.datasource.minIdle=5
spring.datasource.maxActive=20
#連接配接等待逾時時間
spring.datasource.maxWait=60000
#配置隔多久進行一次檢測(檢測可以關閉的空閑連接配接)
spring.datasource.timeBetweenEvictionRunsMillis=60000
#配置連接配接在池中的最小生存時間
spring.datasource.minEvictableIdleTimeMillis=300000
spring.datasource.validationQuery=SELECT 1 FROM DUAL
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
# 打開PSCache,并且指定每個連接配接上PSCache的大小
spring.datasource.poolPreparedStatements=false
spring.datasource.maxPoolPreparedStatementPerConnectionSize=-1
# 配置監控統計攔截的filters,去掉後監控界面sql無法統計,'wall'用于防火牆
# spring.datasource.filters=stat,wall,log4j ,在DataBaseConfig定制stat,wall,log4j,兩者同時配置是交集(避免)
# 通過connectProperties屬性來打開mergeSql功能;慢SQL記錄
spring.datasource.connectionProperties=druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
RedisConfig.java
--------這個類主要是用來配置redisTemplate和redis緩存的。
package com.tinyhelp.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@PropertySource("classpath:/redis.properties")
@EnableCaching
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private Integer port;
@Value("${spring.redis.maxTotal}")
private Integer maxTotal;
@Value("${spring.redis.maxIdle}")
private Integer maxIdle;
@Value("${spring.redis.minIdle}")
private Integer minIdle;
@Value("${spring.redis.maxWait}")
private Integer maxWaitMillis;
@Value("${spring.redis.testOnBorrow}")
private Boolean testOnBorrow;
@Value("${spring.redis.testOnReturn}")
private Boolean testOnReturn;
/**
* jedisPoolConfig
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
jedisPoolConfig.setTestOnReturn(testOnReturn);
return jedisPoolConfig;
}
/**
* redisConnectionFactory
*/
@Bean
public RedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
jedisConnectionFactory.setHostName(host);
jedisConnectionFactory.setPort(port);
jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
return jedisConnectionFactory;
}
/**
* 配置redisTemplate
*/
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
/** Redis 序列化器.
*
* RedisTemplate 預設的系列化類是 JdkSerializationRedisSerializer,用JdkSerializationRedisSerializer序列化的話, 被序列化的對象必須實作Serializable接口。在存儲内容時,除了屬性的内容外還存了其它内容在裡面,總長度長,且不容易閱讀。
*
* Jackson2JsonRedisSerializer 和 GenericJackson2JsonRedisSerializer,兩者都能系列化成 json, 但是後者會在 json 中加入 @class 屬性,類的全路徑包名,友善反系列化。前者如果存放了 List 則在反系列化的時候如果沒指定,TypeReference 則會報錯 java.util.LinkedHashMap cannot be cast to
*/
RedisSerializer<?> genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
RedisSerializer<?> stringRedisSerializer = new StringRedisSerializer();
// 定義RedisTemplate,并設定連接配接工程
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
// key 的序列化采用 StringRedisSerializer
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// value 值的序列化采用 GenericJackson2JsonRedisSerializer
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
// 設定連接配接工廠
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
//配置redis緩存管理器
@Bean
public CacheManager redisCacheManager(RedisTemplate<Object,Object> redisTempate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTempate);
// 設定預設逾時時間,為30分鐘
cacheManager.setDefaultExpiration(1800);
// 設定緩存管理器名稱
List<String> cacheNames = new ArrayList<String>();
cacheNames.add("redisCacheManager");
cacheManager.setCacheNames(cacheNames);
return cacheManager;
}
}
redis.properties
--------host,post,修改成自己的
#連接配接池基本資訊
spring.redis.maxTotal=200
spring.redis.maxIdle=20
spring.redis.minIdle=5
spring.redis.maxWait=3000
spring.redis.testOnBorrow=true
spring.redis.testOnReturn=true
#連接配接工廠
spring.redis.host=
spring.redis.port=
以下是其它配置檔案
------以下兩個java檔案是用于配置druid監控器的,配置完後可以通路http://localhost:8080/{項目名}/druid/index.html,檢視監控。
DruidMonitorServlet.java
package com.tinyhelp.web;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import com.alibaba.druid.support.http.StatViewServlet;
@WebServlet(name="druidMonitorServlet", urlPatterns="/druid/*", initParams={
@WebInitParam(name="allow", value="127.0.0.1"),// IP白名單(沒有配置或者為空,則允許所有通路)
@WebInitParam(name="loginUsername", value="admin"),
@WebInitParam(name="loginPassword", value="123456"),
@WebInitParam(name="resetEnable", value="false")// 禁用HTML頁面上的“Reset All”功能
})
public class DruidMonitorServlet extends StatViewServlet {
/**
* Druid監控服務連接配接器
*/
private static final long serialVersionUID = -425013362240213511L;
}
DruidStatFilter.java
package com.tinyhelp.web;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import com.alibaba.druid.support.http.WebStatFilter;
@WebFilter(filterName="druidStatFilter", urlPatterns="/*", initParams={
@WebInitParam(name="exclusions", value="*.css,*.js,*.gif,*.jpg,*.png,*.ico,/druid/*")//忽略資源
})
public class DruidStatFilter extends WebStatFilter {
/**
* Druid監控過濾器
*/
}
logback.xml
-------日志配置xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.padual.com/java/logback.xsd"
debug="false" scan="true" scanPeriod="30 second">
<property name="PROJECT" value="iorder" />
<property name="ROOT" value="logs/${PROJECT}/" />
<property name="FILESIZE" value="50MB" />
<property name="MAXHISTORY" value="100" />
<timestamp key="DATETIME" datePattern="yyyy-MM-dd HH:mm:ss" />
<!-- 控制台列印 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
</appender>
<!-- ERROR 輸入到檔案,按日期和檔案大小 -->
<appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/error.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- WARN 輸入到檔案,按日期和檔案大小 -->
<appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/warn.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- INFO 輸入到檔案,按日期和檔案大小 -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/info.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- DEBUG 輸入到檔案,按日期和檔案大小 -->
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/debug.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- TRACE 輸入到檔案,按日期和檔案大小 -->
<appender name="TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder charset="utf-8">
<pattern>[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>TRACE</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${ROOT}%d/trace.%i.log</fileNamePattern>
<maxHistory>${MAXHISTORY}</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${FILESIZE}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- SQL相關日志輸出-->
<logger name="org.apache.ibatis" level="INFO" additivity="false" />
<logger name="org.mybatis.spring" level="INFO" additivity="false" />
<logger name="com.github.miemiedev.mybatis.paginator" level="INFO" additivity="false" />
<!-- Logger 根目錄 -->
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="DEBUG" />
<appender-ref ref="ERROR" />
<appender-ref ref="WARN" />
<appender-ref ref="INFO" />
<appender-ref ref="TRACE" />
</root>
</configuration>
generatorConfig.xml
--------mybatis逆向工程,使用maven插件,這是配置檔案
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<properties resource="jdbc.properties" />
<context id="DBTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自動生成的注釋 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<jdbcConnection driverClass="${spring.datasource.driverClassName}"
connectionURL="${spring.datasource.url}" userId="${spring.datasource.username}" password="${spring.datasource.password}">
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!-- 預設false,把JDBC DECIMAL 和 NUMERIC 類型解析為 Integer,為 true時把JDBC DECIMAL 和
NUMERIC 類型解析為java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成PO類的位置 -->
<javaModelGenerator targetPackage="com.tinyhelp.entity" targetProject="./src/main/java">
<!-- enableSubPackages:是否讓schema作為包的字尾 -->
<property name="enableSubPackages" value="true" />
<!-- 從資料庫傳回的值被清理前後的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射檔案生成的位置 -->
<sqlMapGenerator targetPackage="mappers" targetProject="./src/main/resources">
<!-- enableSubPackages:是否讓schema作為包的字尾 -->
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.tinyhelp.dao" targetProject="./src/main/java">
<!-- enableSubPackages:是否讓schema作為包的字尾 -->
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 指定資料庫表,注釋的已經生成過了 -->
<!-- <table tableName="th_sys_user" domainObjectName="User"></table> -->
<!-- <table tableName="th_sys_admin" domainObjectName="Admin"></table> -->
<table tableName=""></table>
</context>
</generatorConfiguration>