最近在给学生们讲Spring+Mybatis整合,根据有的学生反映还是基于注解实现整合便于理解,毕竟在先前的工作中团队里还没有人完全舍弃配置文件进行项目开发,由于这两个原因,我索性参考spring官方文档研究出完全基于注解整合ssm框架。毕竟无配置化也是Spring官方所推行的,要不SpringBoot存在的意义为何嘛
一。整合思路
1)目标:毫无保留的将配置文件的所有配置项改变注解加创建对象的方式实现
2)Spring提供的 @Bean @Configuration @ComponentScan @EnableTransactionManagement @EnableWebMvc 等 需要知道其含义
二。创建spring-mvc的web项目
1) 项目结构目录:
在这里web.xml里不写任何配置
三。在config包下分别创建配置类与属性文件
1. AppConfig.java
package com.bdqn.lyrk.ssm.study.app; import com.alibaba.druid.pool.DruidDataSource; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.sql.DataSource; import java.io.IOException; /** * spring的配置类 * * @author chen.nie * @date 2018/6/24 **/ @Configuration //表明此类是配置类 @ComponentScan // 扫描自定义的组件(repository service component controller) @PropertySource("classpath:application.properties") // 读取application.properties @MapperScan("com.bdqn.lyrk.ssm.study.app.mapper") //扫描Mybatis的Mapper接口 @EnableTransactionManagement //开启事务管理 public class AppConfig { /** * 配置数据源 * * @date 2018/6/24 **/ @Bean public DataSource dataSource(PropertiesConfig propertiesConfig) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUsername(propertiesConfig.getUserName()); dataSource.setPassword(propertiesConfig.getPassword()); dataSource.setUrl(propertiesConfig.getUrl()); dataSource.setDriverClassName(propertiesConfig.getDriverClass()); return dataSource; } /** * 配置mybatis的SqlSessionFactoryBean * * @param dataSource * @param propertiesConfig * @return */ @Bean public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource, PropertiesConfig propertiesConfig) throws IOException { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); sqlSessionFactoryBean.setTypeAliasesPackage(propertiesConfig.getMybatisTypeAliasPackages()); // 动态获取SqlMapper PathMatchingResourcePatternResolver classPathResource = new PathMatchingResourcePatternResolver(); sqlSessionFactoryBean.setMapperLocations(classPathResource.getResources(propertiesConfig.getMapperLocations())); return sqlSessionFactoryBean; } /** * 配置spring的声明式事务 * * @return */ @Bean public PlatformTransactionManager transactionManager(DataSource dataSource) { DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource); return dataSourceTransactionManager; } @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); return propertySourcesPlaceholderConfigurer; } }
没什么好说的,这里主要创建Spring与Mybatis整合的相关对象以及声明式事务切面,我们把配置文件中的东西通通用java代码创建,注意@Bean注解的使用
2.DispatcherConfig
1 package com.bdqn.lyrk.ssm.study.config; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.context.annotation.Configuration; 6 import org.springframework.web.servlet.config.annotation.EnableWebMvc; 7 import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 8 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 9 import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 10 import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; 11 import org.springframework.web.servlet.view.InternalResourceViewResolver; 12 import org.springframework.web.servlet.view.JstlView; 13 14 import java.util.Properties; 15 16 @Configuration 17 @EnableWebMvc 18 public class DispatcherConfig extends WebMvcConfigurerAdapter { 19 20 21 @Autowired 22 private PropertyConfig propertyConfig; 23 24 @Bean 25 public InternalResourceViewResolver internalResourceViewResolver() { 26 InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver(); 27 internalResourceViewResolver.setViewClass(JstlView.class); 28 internalResourceViewResolver.setPrefix(propertyConfig.getWebViewPrefix()); 29 internalResourceViewResolver.setSuffix(propertyConfig.getWebViewSuffix()); 30 return internalResourceViewResolver; 31 } 32 33 /** 34 * 设置统一错误处理要跳转的视图 35 * 36 * @return 37 */ 38 @Bean 39 public SimpleMappingExceptionResolver simpleMappingExceptionResolver() { 40 SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver(); 41 Properties properties = new Properties(); 42 properties.getProperty("java.lang.Exception", "error"); 43 simpleMappingExceptionResolver.setExceptionMappings(properties); 44 return simpleMappingExceptionResolver; 45 } 46 47 /** 48 * 添加静态资源 49 * 50 * @param registry 51 */ 52 @Override 53 public void addResourceHandlers(ResourceHandlerRegistry registry) { 54 registry.addResourceHandler(propertyConfig.getWebStaticHandler()).addResourceLocations(propertyConfig.getWebStaticResource()).setCachePeriod(propertyConfig.getWebStaticCachedPeriod()); 55 } 56 57 /** 58 * 添加拦截器 59 * 60 * @param registry 61 */ 62 @Override 63 public void addInterceptors(InterceptorRegistry registry) { 64 super.addInterceptors(registry); 65 } 66 }
此处配置SpringMVC的视图解析器,静态资源等,依旧照搬配置文件中的代码
3.PropertiesConfig
package com.bdqn.lyrk.ssm.study.config; 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.context.support.PropertySourcesPlaceholderConfigurer; @Configuration @PropertySource("classpath:application.properties") public class PropertyConfig { @Value("${spring.datasource.url}") private String url; @Value("${spring.datasource.driver}") private String driver; @Value("${spring.datasource.user}") private String user; @Value("${spring.datasource.password}") private String password; @Value("${spring.web.view.prefix}") private String webViewPrefix; @Value("${spring.web.view.suffix}") private String webViewSuffix; @Value("${spring.web.static.handler}") private String webStaticHandler; @Value("${spring.web.static.resource}") private String webStaticResource; @Value("${spring.web.static.cache.period}") private Integer webStaticCachedPeriod; @Value("${mybatis.type.alias.package}") private String mybatisTypeAliasPackage; public String getWebViewPrefix() { return webViewPrefix; } public String getWebViewSuffix() { return webViewSuffix; } public String getWebStaticHandler() { return webStaticHandler; } public String getWebStaticResource() { return webStaticResource; } public Integer getWebStaticCachedPeriod() { return webStaticCachedPeriod; } public String getMybatisTypeAliasPackage() { return mybatisTypeAliasPackage; } public String getUrl() { return url; } public String getDriver() { return driver; } public String getUser() { return user; } public String getPassword() { return password; } @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } }
此处用于读取application.properties的文件内容 注意@Value与@PropertySource的含义
4.MyWebAppInitializer
1 package com.bdqn.lyrk.ssm.study.config; 2 3 import org.springframework.web.filter.CharacterEncodingFilter; 4 import org.springframework.web.servlet.DispatcherServlet; 5 import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; 6 7 import javax.servlet.Filter; 8 import javax.servlet.ServletContext; 9 import javax.servlet.ServletException; 10 11 /** 12 * 初始化servlet WebApplicationContext 相关 13 * 14 * @author chen.nie 15 * @date 2017/12/28 16 **/ 17 public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 18 19 @Override 20 protected Class<?>[] getRootConfigClasses() { 21 return new Class[]{AppConfig.class}; 22 } 23 24 @Override 25 protected Class<?>[] getServletConfigClasses() { 26 return new Class[]{DispatcherServlet.class}; 27 } 28 29 @Override 30 protected String[] getServletMappings() { 31 return new String[]{"/"}; 32 } 33 34 35 /** 36 * 添加过滤器 37 * 38 * @return 39 */ 40 @Override 41 protected Filter[] getServletFilters() { 42 CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); 43 characterEncodingFilter.setEncoding("UTF-8"); 44 characterEncodingFilter.setForceEncoding(true); 45 return new Filter[]{characterEncodingFilter}; 46 } 47 }
在这里请大家关注一下这个类,这段代码的含义和配置SpringMVC的含义一样:
1 <web-app> 2 <context-param> 3 <param-name>contextConfigLocation</param-name> 4 <param-value>/WEB-INF/root-context.xml</param-value> 5 </context-param> 6 <servlet> 7 <servlet-name>dispatcher</servlet-name> 8 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 9 <init-param> 10 <param-name>contextConfigLocation</param-name> 11 <param-value></param-value> 12 </init-param> 13 <load-on-startup>1</load-on-startup> 14 </servlet> 15 <servlet-mapping> 16 <servlet-name>dispatcher</servlet-name> 17 <url-pattern>/</url-pattern> 18 </servlet-mapping> 19 <listener> 20 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 21 </listener> 22 </web-app>
5. application.properties
#数据库连接 spring.datasource.user=root spring.datasource.password=root spring.datasource.driver=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/MySchool?characterEncoding=utf-8&useSSL=false #web设置相关 spring.web.view.prefix=/WEB-INF/jsp/ spring.web.view.suffix=.jsp spring.web.static.handler=/assets/** spring.web.static.resource=classpath:/assets/ spring.web.static.cache.period=360000 #mybatis设置相关 mybatis.type.alias.package=com.bdqn.lyrk.ssm.study.entity
6.创建MyBatis对应的mapper
package com.bdqn.lyrk.ssm.study.mapper; import com.bdqn.lyrk.ssm.study.entity.StudentEntity; import org.apache.ibatis.annotations.Select; import java.util.List; public interface StudentMapper { @Select("select * from Student") List<StudentEntity> selectAll(); }
7.创建业务逻辑
1 package com.bdqn.lyrk.ssm.study.service.impl; 2 3 import com.bdqn.lyrk.ssm.study.entity.StudentEntity; 4 import com.bdqn.lyrk.ssm.study.mapper.StudentMapper; 5 import com.bdqn.lyrk.ssm.study.service.IStudentService; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.stereotype.Service; 8 import org.springframework.transaction.annotation.Transactional; 9 10 import java.util.List; 11 12 @Service 13 public class StudentServiceImpl implements IStudentService { 14 @Autowired 15 private StudentMapper studentMapper; 16 17 18 @Override 19 public List<StudentEntity> selectAll() { 20 return studentMapper.selectAll(); 21 } 22 23 @Transactional 24 @Override 25 public int save(StudentEntity studentEntity) { 26 return 0; 27 } 28 29 30 }
8.创建Controller
package com.bdqn.lyrk.ssm.study.controller; import com.bdqn.lyrk.ssm.study.entity.StudentEntity; import com.bdqn.lyrk.ssm.study.service.IStudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; import java.util.List; @Controller public class IndexController { @Autowired private IStudentService studentService; @GetMapping("/index") public String index(ModelMap modelMap) { List<StudentEntity> list = studentService.selectAll(); modelMap.put("students", list); return "index"; } }
9.index.jsp文件中内容
<%-- Created by IntelliJ IDEA. User: chen.nie Date: 2017/12/23 Time: 下午8:40 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>$Title$</title> </head> <body> <c:forEach items="${students}" var="student"> ${student.stuName} </c:forEach> </body> </html>
10.启动tomcat后访问http://localhost:8080/portal/index得到如下界面
OK!大功告成,注意前4步里面注解的运用,后面的步骤和往常的写法无异,想必大家都很熟悉了吧。