随着spring版本迭代更新,现在越来越倡导不使用复杂繁琐的配置文件来配置项目,下面介绍纯粹使用java 配置类来配置spring、springmvc、mybatis;
环境:java 8 + maven + IDEA + mysql
新建maven web项目:(这个就不介绍了,网上一大堆的教程),下面进入正题;
一、项目所需依赖jar
4.0.0
com.open.ssm
ssm-demo
0.0.1-SNAPSHOT
war
UTF-8
4.12
4.3.0.RELEASE
2.5.0
5.1.37
1.2.3
1.7.12
2.4
1.3.2
3.2.2
3.3.2
1.10
3.1.0
1.0.16
2.0.5
2.7.18
junit
junit
${junit.version}
test
com.alibaba
fastjson
${fastjson.version}
org.springframework
spring-core
${spring.version}
org.springframework
spring-beans
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-tx
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.springframework
spring-jdbc
${spring.version}
org.springframework
spring-test
${spring.version}
test
org.springframework
spring-aspects
${spring.version}
com.fasterxml.jackson.core
jackson-annotations
${jackson.version}
com.fasterxml.jackson.core
jackson-core
${jackson.version}
com.fasterxml.jackson.core
jackson-databind
${jackson.version}
mysql
mysql-connector-java
${mysql-connector-java.version}
commons-io
commons-io
${commons-io.version}
commons-fileupload
commons-fileupload
${commons-fileupload.version}
commons-collections
commons-collections
${commons-collections.version}
org.apache.commons
commons-lang3
${commons-lang3.version}
commons-codec
commons-codec
${commons-codec.version}
org.slf4j
slf4j-log4j12
${slf4j.version}
javax.servlet
javax.servlet-api
${javax.servlet-api.version}
provided
javax.servlet
jstl
1.2
com.alibaba
druid
${druid.version}
com.baomidou
mybatis-plus
${mybatis-plus.version}
com.ibeetl
beetl
${beetl.version}
org.projectlombok
lombok
1.16.12
ssm-demo
org.apache.maven.plugins
maven-war-plugin
2.5
false
org.apache.tomcat.maven
tomcat7-maven-plugin
8088
/
二、在maven项目中新建几个基本包
三、spring配置类
1、webconfig 配置类,继承WebMvcConfigurerAdapter
packagecom.study.ssm.config;importorg.beetl.ext.spring.BeetlGroupUtilConfiguration;importorg.beetl.ext.spring.BeetlSpringViewResolver;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;importorg.springframework.core.io.DefaultResourceLoader;importorg.springframework.core.io.support.ResourcePatternResolver;importorg.springframework.core.io.support.ResourcePatternUtils;importorg.springframework.web.multipart.commons.CommonsMultipartResolver;importorg.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;importorg.springframework.web.servlet.config.annotation.EnableWebMvc;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;/*** Web Configuration Class
*
*@authorEnzoLuo
* @date 2018/10/22*/@Configuration
@EnableWebMvc
@ComponentScan("com.study.ssm.controller")public class WebConfig extendsWebMvcConfigurerAdapter {@Bean(initMethod= "init")publicBeetlGroupUtilConfiguration getBeetlGroupUtilConfiguration() {
BeetlGroupUtilConfiguration beetlGroupUtilConfiguration= newBeetlGroupUtilConfiguration();
ResourcePatternResolver patternResolver= ResourcePatternUtils.getResourcePatternResolver(newDefaultResourceLoader());
beetlGroupUtilConfiguration.setConfigFileResource(patternResolver.getResource("classpath:beetl.properties"));returnbeetlGroupUtilConfiguration;
}
@Bean(name= "viewResolver")publicBeetlSpringViewResolver getBeetlSpringViewResolver() {
BeetlSpringViewResolver beetlSpringViewResolver= newBeetlSpringViewResolver();
beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
beetlSpringViewResolver.setOrder(0);returnbeetlSpringViewResolver;
}//静态资源的处理
@Overridepublic voidconfigureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
2、RootConfig 配置类 功能:配置基本的扫描包
packagecom.study.ssm.config;importorg.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Import;/*** Root Configuration Class
*
*@authorEnzoLuo
* @date 2018/10/22*/@Configuration
@ComponentScan(basePackages={ "com.study.ssm.config", "com.study.ssm.repository", "com.study.ssm.service"})public classRootConfig {
@BeanpublicBeanNameAutoProxyCreator proxycreate(){
BeanNameAutoProxyCreator proxycreate= newBeanNameAutoProxyCreator();
proxycreate.setProxyTargetClass(true);
proxycreate.setBeanNames("*ServiceImpl");
proxycreate.setInterceptorNames("transactionInterceptor");returnproxycreate;
}
}
3、新建 WebAppInitializer类 继承 AbstractAnnotationConfigDispatcherServletInitializer
这里是把刚才写的两个配置类加载进来
packagecom.study.ssm.config;importorg.apache.log4j.Logger;importorg.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;/*** Application gateway and load config class
*
*@authorEnzoLuo
* @date 2018/10/22*/
public class WebAppInitializer extendsAbstractAnnotationConfigDispatcherServletInitializer {private final static Logger LOG = Logger.getLogger(WebAppInitializer.class);
@Overrideprotected Class>[] getRootConfigClasses() {
LOG.info("------root配置类初始化------");return new Class>[] { RootConfig.class};
}
@Overrideprotected Class>[] getServletConfigClasses() {
LOG.info("------web配置类初始化------");return new Class>[] { WebConfig.class};
}
@OverrideprotectedString[] getServletMappings() {
LOG.info("------映射根路径初始化------");return new String[]{ "/" };//请求路径映射,根路径
}
}
四、新建 beetl.properties 用来配置视图解析器
这个文件的引入是在WebConfig 里面
#classpath 根路径,即模板资源路径
RESOURCE.root=/WEB-INF/view/#是否检测文件变化,开发用true合适,但线上要改为false
RESOURCE.autoCheck= true
五、加上一个 log4j.properties
### set log levels ###
log4j.rootLogger = INFO , C , D , E
### console ###
log4j.appender.C = org.apache.log4j.ConsoleAppender
log4j.appender.C.Target = System.out
log4j.appender.C.layout = org.apache.log4j.PatternLayout
log4j.appender.C.layout.ConversionPattern = [ssm-demo][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n
### log file ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ../logs/ssm-demo.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = INFO
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = [ssm-demo][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n
### exception ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = ../logs/ssm-demo_error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = [ssm-demo][%p] [%-d{yyyy-MM-dd HH:mm:ss}] %C.%M(%L) | %m%n
暂时写一个 indexController 测试一下;
packagecom.study.ssm.controller;importjava.io.File;importjava.io.IOException;importjava.util.UUID;importjavax.servlet.http.HttpServletRequest;importorg.apache.log4j.Logger;importorg.springframework.stereotype.Controller;importorg.springframework.ui.Model;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.multipart.MultipartFile;importorg.springframework.web.servlet.ModelAndView;/*** index
*
*@authorEnzoLuo
* @date 2018/10/22*/@Controllerpublic classIndexController {
@SuppressWarnings("unused")private final static Logger LOG = Logger.getLogger(IndexController.class);
@GetMapping("/index")publicString index(){return "ssm.html";
}
}
记得在WEB-INF 下新建一个view目录,然后随便加一个 ssm.html 文件
启动项目访问 、如果正确访问到ssm.html 则说明配置成功
注:别忘了install 一下,我之前又一次出错了,怎么都不到原因,最后突然想起来,忘记install了
第二阶段:配置mybatis
一:jdbc.properties
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/zhidevelop
spring.datasource.username=root
spring.datasource.password=root
#连接池配置
spring.datasource.initialSize=5spring.datasource.minIdle=5spring.datasource.maxActive=20#连接等待超时时间
spring.datasource.maxWait=60000#配置隔多久进行一次检测(检测可以关闭的空闲连接)
spring.datasource.timeBetweenEvictionRunsMillis=60000#配置连接在池中的最小生存时间
spring.datasource.minEvictableIdleTimeMillis=300000spring.datasource.validationQuery=SELECT 1FROM DUAL
spring.datasource.testWhileIdle=truespring.datasource.testOnBorrow=falsespring.datasource.testOnReturn=false# 打开PSCache,并且指定每个连接上PSCache的大小
spring.datasource.poolPreparedStatements=truespring.datasource.maxPoolPreparedStatementPerConnectionSize=20# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
spring.datasource.filters=stat,wall,log4j
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
二、新建 DruidDataSourceConfig 配置类
package com.study.ssm.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.log4j.Logger;
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.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.interceptor.TransactionInterceptor;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;
/**
* DataSource Configuration Class
*
* @author EnzoLuo
* @date 2018/10/22
*/
@Configuration
@PropertySource("classpath:/jdbc.properties")
@MapperScan(basePackages="com.study.ssm.repository")
public class DruidDataSourceConfig {
private final static Logger LOG = Logger.getLogger(DruidDataSourceConfig.class);
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driverClassName}")
private String driverClassName;
@Value("${spring.datasource.initialSize}")
private int initialSize;
@Value("${spring.datasource.minIdle}")
private int minIdle;
@Value("${spring.datasource.maxActive}")
private int maxActive;
@Value("${spring.datasource.maxWait}")
private int maxWait;
@Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
private int timeBetweenEvictionRunsMillis;
@Value("${spring.datasource.minEvictableIdleTimeMillis}")
private int minEvictableIdleTimeMillis;
@Value("${spring.datasource.validationQuery}")
private String validationQuery;
@Value("${spring.datasource.testWhileIdle}")
private boolean testWhileIdle;
@Value("${spring.datasource.testOnBorrow}")
private boolean testOnBorrow;
@Value("${spring.datasource.testOnReturn}")
private boolean testOnReturn;
@Value("${spring.datasource.poolPreparedStatements}")
private boolean poolPreparedStatements;
@Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
private int maxPoolPreparedStatementPerConnectionSize;
@Value("${spring.datasource.filters}")
private String filters;
@Value("{spring.datasource.connectionProperties}")
private String connectionProperties;
@Bean //声明其为Bean实例
public DataSource dataSource(){
LOG.info("Initialize the data source...");
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(this.dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
//configuration
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);
try {
datasource.setFilters(filters);
} catch (SQLException e) {
LOG.error("druid configuration initialization filter", e);
}
datasource.setConnectionProperties(connectionProperties);
return datasource;
}
/*
//JdbcTemplate的配置
@Bean
public JdbcTemplate jdbcTemplate(){
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource());
return jdbcTemplate;
}
@Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(){
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource());
return namedParameterJdbcTemplate;
}*/
//全局配置
public GlobalConfiguration globalConfigurationBean(){
GlobalConfiguration globalConfiguration = new GlobalConfiguration();
globalConfiguration.setIdType(2);//AUTO->`0`("数据库ID自增")、INPUT->`1`(用户输入ID")、ID_WORKER->`2`("全局唯一ID")、UUID->`3`("全局唯一ID")
globalConfiguration.setDbColumnUnderline(true);//全局表为下划线命名设置 true
return globalConfiguration;
}
//mybatis的配置
@Bean
public MybatisSqlSessionFactoryBean sqlSessionFactoryBean() throws IOException{
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
//SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();//mybatis-plus插件类
sqlSessionFactoryBean.setDataSource(dataSource());//数据源
sqlSessionFactoryBean.setGlobalConfig(globalConfigurationBean());//MP全局注入
sqlSessionFactoryBean.setMapperLocations(resourcePatternResolver.getResources("classpath*:mybatis/mappers/*.xml"));
sqlSessionFactoryBean.setTypeAliasesPackage("com.study.ssm.entity");//别名,让*Mpper.xml实体类映射可以不加上具体包名
return sqlSessionFactoryBean;
}
@Bean(name = "transactionManager")
public DataSourceTransactionManager dataSourceTransactionManager(){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
dataSourceTransactionManager.setDataSource(dataSource());
return dataSourceTransactionManager;
}
@Bean(name="transactionInterceptor")
public TransactionInterceptor interceptor(){
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionManager(dataSourceTransactionManager());
Properties transactionAttributes = new Properties();
transactionAttributes.setProperty("save*", "PROPAGATION_REQUIRED");
transactionAttributes.setProperty("del*", "PROPAGATION_REQUIRED");
transactionAttributes.setProperty("update*", "PROPAGATION_REQUIRED");
transactionAttributes.setProperty("get*", "PROPAGATION_REQUIRED,readOnly");
transactionAttributes.setProperty("find*", "PROPAGATION_REQUIRED,readOnly");
transactionAttributes.setProperty("*", "PROPAGATION_REQUIRED");
interceptor.setTransactionAttributes(transactionAttributes);
return interceptor;
}
/*
//放这里会导致@value注解获取不到配置的值,移到RootConfig
@Bean
public BeanNameAutoProxyCreator proxycreate(){
BeanNameAutoProxyCreator proxycreate = new BeanNameAutoProxyCreator();
proxycreate.setProxyTargetClass(true);
proxycreate.setBeanNames("*ServiceImpl");
proxycreate.setInterceptorNames("transactionInterceptor");
return proxycreate;
}*/
}
三、再次启动项目,如果正常启动则项目配置dataSource配置正确
第三阶段:测试mybatis继承情况:
一、新建UserDTO 实体类
注:我这里使用lombok 插件,如果没有的话可以下一个或者,自己手动增加get、set方法
package com.study.ssm.entity;
import lombok.Getter;
import lombok.Setter;
/**
* 用户实体类
*
* @author EnzoLuo
* @date 2018/10/22
*/
@Getter
@Setter
public class UserDTO {
private Integer id;
private String name;
private String password;
@Override
public String toString() {
return super.toString();
}
}
二、添加mapper文件:这里注意路径,在DruidDataSourceConfig 会加载进去
select * from user where id =#{id}
UPDATE user SET name=#{name} WHERE id=#{id}
三、UserRepository
packagecom.study.ssm.repository;importcom.study.ssm.entity.UserDTO;importorg.apache.ibatis.annotations.Param;/*** UserRepository
*
*@authorEnzoLuo
* @date 2018/10/22*/
public interfaceUserRepository {
UserDTO findById(@Param("id") Integer id);voidupdateUser(UserDTO userDTO);
}
四、UserService和UserServiceImpl
packagecom.study.ssm.service;importcom.study.ssm.entity.UserDTO;/*** UserService
*
*@authorEnzoLuo
* @date 2018/10/22*/
public interfaceUserService {
UserDTO findById(Integer id);voidupdateUserById(UserDTO userDTO);
}
packagecom.study.ssm.service.spring;importcom.study.ssm.entity.UserDTO;importcom.study.ssm.repository.UserRepository;importcom.study.ssm.service.UserService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;/*** UserServiceImpl
*
*@authorEnzoLuo
* @date 2018/10/22*/@Servicepublic class UserServiceImpl implementsUserService {
@AutowiredprivateUserRepository userRepository;
@OverridepublicUserDTO findById(Integer id) {
UserDTO userDTO=userRepository.findById(id);returnuserDTO;
}
@Overridepublic voidupdateUserById(UserDTO userDTO) {
userRepository.updateUser(userDTO);
}
}
五、写一个UserController 测试一下
packagecom.study.ssm.controller;importcom.study.ssm.entity.UserDTO;importcom.study.ssm.service.UserService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;/*** UserController
*
*@authorEnzoLuo
* @date 2018/10/22*/@RestControllerpublic classUserController {
@AutowiredprivateUserService userService;
@GetMapping("/getUserById")public UserDTO getUserById(@RequestParam(name = "id") Integer id) {
UserDTO userDTO=userService.findById(id);returnuserDTO;
}
@PostMapping("/updateUserById")publicString updateUser(){try{
UserDTO userDTO= newUserDTO();
userDTO.setId(1);
userDTO.setName("enzoluo");
userDTO.setPassword("456");
userService.updateUserById(userDTO);
}catch(Exception e){
e.printStackTrace();return "update failed";
}return "update success";
}
}
结果:查询
修改:
再次查询:
打完收工,谢谢阅读!
githup出了点问题,稍后会将代码放上去。