Spring之路(35)–使用JavaConfig配置Spring+SpringMVC+MyBatis(SSM)项目完整实例
2020/2/14 8:17:11
本文主要是介绍Spring之路(35)–使用JavaConfig配置Spring+SpringMVC+MyBatis(SSM)项目完整实例,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
背景
本篇的表面目的,就时去掉烦人的xml文件,全部使用JavaConfig(如果要表达的更加严谨,其实除了JavaConfig配置,还有注解配置)开发一个SSM项目。
真实目的是演示,xml、注解、JavaConfig只是配置bean的不同方式,功能目的是一致的。在本系列文章中,我曾经很多次做过一件事——将xml+注解配置的SSM
项目翻译为JavaConfig+注解配置的SSM项目
,目的就是让大家深刻体会这一点。理解三种配置方式殊途同归,是学习和理解Spring的基石。
实际上SpringBoot跟全部使用JavaConfig+注解配置的SSM项目,高度相似,除了更加简洁了点,技术上没有多少新增的内容。所以如果Spring基础掌握的好,学习SpringBoot,简直就是不费吹灰之力!当然,后续Spring之路
系列完结之后,我也会继续推出SpringBoot之路
,敬请期待。
本篇讲述方式
我们会通过逐一对比的方式,逐一对比上篇文章中xml配置的各个步骤,然后将步骤修改为JavaConfig配置,以便于大家体会理解。坐稳了老弟,开整~~~~
1 新建项目
原来:
File-New-Other Project-Dynamic Web Project,建立一个动态网站项目,项目名称xmlssmdemo
。
修改:
项目名称改为jcssmdemo
,jc为JavaConfig缩写,因为javaconfigssmdemo这个项目名称实在是太长了。
2 导入jar包
原来:
除了spring相关的jar包(已经指示过多次不再具体指示),还需要导入下面的jar包:
commons-logging-1.2.jar
日志相关jackson-annotations-2.8.0.jar
json相关jackson-core-2.8.0.jar
json相关jackson-databind-2.8.0.jar
json相关mysql-connector-java-5.1.48.jar
mysql驱动druid-1.1.21.jar
数据库连接池mybatis-3.5.3.jar
mybatis相关mybatis-spring-2.0.3.jar
mybatis-spring相关
修改:这一步不需要修改
3 配置web项目
原来:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>xmlssmdemo</display-name> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- 引入spring-config.xml配置文件,该文件用来配置spring容器 --> <param-value>/WEB-INF/spring-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <!-- 配置DispatcherServlet对应所有请求(*表示所有) --> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
修改:
通过WebInit引导web项目加载,指定Spring容器的配置类为SpringConfig.class,注意WebInit本身并不是Spring容器的组件,而是通过继承AbstractAnnotationConfigDispatcherServletInitializer实现引导容器加载的作用。
package org.maoge.jcssmdemo; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return null; } @Override protected Class<?>[] getServletConfigClasses() { // <!-- 引入SpringConfig配置类,该类用来配置spring容器 --> return new Class[] { SpringConfig.class }; } @Override protected String[] getServletMappings() { // <!-- 配置DispatcherServlet对应所有请求(*表示所有) --> return new String[] { "/*" }; } }
4 配置Spring容器
这一步的配置比较复杂,我们要详细说明。
将xml配置改为配置类
原来:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> </beans>
改为:
package org.maoge.jcssmdemo; import org.springframework.context.annotation.Configuration; @Configuration // 表明该类是一个Spring配置类 public class SpringConfig { }
注意这两个都是对Spring容器配置的描述,没啥功能区别,但是很明显类的方式更加简洁点。
修改sqlSessionFactory配置
原来
<!-- 第一步,配置MyBatis用来操作数据,sqlSessionFactory就是MyBatis中用来操作数据库的 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 引入Mybatis的配置文件,MyBatis组件需要它 --> <property name="configLocation" value="classpath:org/maoge/xmlssmdemo/config/mybatis-config.xml" /> </bean>
改为
@Bean // 配置sqlSessionFactory public SqlSessionFactoryBean sqlSessionFactory() { SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean(); sqlSessionFactory.setDataSource(dataSource()); // <!-- 引入Mybatis的配置文件,MyBatis组件需要它 --> Resource resource = new ClassPathResource("org/maoge/jcssmdemo/config/mybatis-config.xml"); sqlSessionFactory.setConfigLocation(resource); return sqlSessionFactory; }
可以看出没啥区别,一个是xml定义bean,一个是通过方法添加@Bean注册bean;一个是通过property标签注入依赖项,一个是通过setter方法注入依赖项。
修改dataSource配置
原来
<!-- 第二步,配置数据源,可以看到sqlSessionFactory需要注入该数据源 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&characterEncoding=utf-8"></property> <property name="username" value="root"></property> <property name="password" value="xxx"></property> </bean>
改为
@Bean // 配置数据源 public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&characterEncoding=utf-8"); dataSource.setUsername("root"); dataSource.setPassword("xxx"); return dataSource; }
没啥好说的,一个意思。
修改MapperScannerConfigurer配置
原来
<!-- 第三步,将org.maoge.xmlssmdemo.dao包下的类注册为bean,注意此处是注册为MyBatis方式管理的可操作数据库的bean --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> <property name="basePackage" value="org.maoge.xmlssmdemo.dao" /> </bean>
改为
@Bean public MapperScannerConfigurer initMapperScannerConfigurer() { MapperScannerConfigurer msc = new MapperScannerConfigurer(); msc.setSqlSessionFactoryBeanName("sqlSessionFactory"); // 扫描包 msc.setBasePackage("org.maoge.jcssmdemo.dao"); return msc; }
没啥好说的,一个意思。
修改扫描包
原来
<!-- 第四步,扫描控制器层和服务层 --> <context:component-scan base-package="org.maoge.xmlssmdemo.controller" /> <context:component-scan base-package="org.maoge.xmlssmdemo.service" />
改为
@Configuration // 表明该类是一个Spring配置类 @ComponentScan({ "org.maoge.jcssmdemo.controller", "org.maoge.jcssmdemo.service" }) // 对应第四步,扫描包 public class SpringConfig extends WebMvcConfigurerAdapter { }
通过标签指定扫描,改为了通过注解。
其他配置
剩下的两个配置通过添加@EnableWebMvc
注解和addResourceHandlers
方法实现,此处我们给出配置类的最终完整代码:
原来
<!--第五步,开启通过注解配置访问路径与方法的匹配 --> <mvc:annotation-driven /> <!--第六步,配置静态资源映射 --> <mvc:resources mapping="/static/**" location="/static/" />
新的配置类完整代码
package org.maoge.jcssmdemo; import javax.sql.DataSource; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.mapper.MapperScannerConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import com.alibaba.druid.pool.DruidDataSource; @Configuration // 表明该类是一个Spring配置类 @ComponentScan({ "org.maoge.jcssmdemo.controller", "org.maoge.jcssmdemo.service" }) // 对应第四步,扫描包 @EnableWebMvc // 实现SpringMVC功能 public class SpringConfig extends WebMvcConfigurerAdapter { @Bean // 配置sqlSessionFactory public SqlSessionFactoryBean sqlSessionFactory() { SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean(); sqlSessionFactory.setDataSource(dataSource()); // <!-- 引入Mybatis的配置文件,MyBatis组件需要它 --> Resource resource = new ClassPathResource("org/maoge/jcssmdemo/config/mybatis-config.xml"); sqlSessionFactory.setConfigLocation(resource); return sqlSessionFactory; } @Bean // 配置数据源 public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&characterEncoding=utf-8"); dataSource.setUsername("root"); dataSource.setPassword("xxx"); return dataSource; } @Bean public MapperScannerConfigurer initMapperScannerConfigurer() { MapperScannerConfigurer msc = new MapperScannerConfigurer(); msc.setSqlSessionFactoryBeanName("sqlSessionFactory"); // 扫描包 msc.setBasePackage("org.maoge.jcssmdemo.dao"); return msc; } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("/static/"); } }
注意以下部分就跟之前基本一样了,除了项目名称和包名称,具体如下:
5、配置mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <mappers><!-- 映射器告诉MyBatis到哪里去找映射文件 --> <mapper resource="org/maoge/jcssmdemo/config/BlogMapper.xml" /> </mappers> </configuration>
6、编写映射文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="org.maoge.jcssmdemo.dao.BlogDao"> <!-- 获取一个 --> <select id="getById" parameterType="Long" resultType="org.maoge.jcssmdemo.xdo.BlogDo"> select * from blog where id = #{id} </select> <!-- 获取列表 --> <select id="getList" resultType="org.maoge.jcssmdemo.xdo.BlogDo"> select * from blog </select> <!-- 插入 --> <insert id="insert" parameterType="org.maoge.jcssmdemo.xdo.BlogDo"> insert into blog(author,content,title)values(#{author},#{content},#{title}) </insert> <!-- 更新 --> <update id="update" parameterType="org.maoge.jcssmdemo.xdo.BlogDo"> update blog set author=#{author},content=#{content},title=#{title} where id=#{id} </update> <!-- 删除 --> <delete id="delete" parameterType="Long"> delete from blog where id=#{id} </delete> </mapper>
7、开发各层逻辑代码
package org.maoge.jcssmdemo.dao; import java.util.List; import org.maoge.jcssmdemo.xdo.BlogDo; import org.springframework.stereotype.Repository; @Repository public interface BlogDao { BlogDo getById(Long id); List<BlogDo> getList(); int insert(BlogDo blog); int update(BlogDo blog); int delete(Long id); }
package org.maoge.jcssmdemo.xdo; /** * @theme 数据对象--博客 * @author maoge * @date 2020-01-29 */ public class BlogDo { private Long id; private String title; private String author; private String content; // 省略get get
package org.maoge.jcssmdemo.service; import java.util.List; import org.maoge.jcssmdemo.dao.BlogDao; import org.maoge.jcssmdemo.xdo.BlogDo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class BlogService { @Autowired private BlogDao blogDao; /** * 获取博客列表 */ public List<BlogDo> getBlogList() { return blogDao.getList(); } /** * 按id获取博客信息 */ public BlogDo getBlogById(Long id) { return blogDao.getById(id); } /** * 新增博客 */ public void addBlog(BlogDo blog) { blogDao.insert(blog); } /** * 根据博客id更新博客信息 */ public void updateBlog(BlogDo blog) { blogDao.update(blog); } /** * 根据博客id删除对应博客 */ public void deleteBlog(Long id) { blogDao.delete(id); } }
package org.maoge.jcssmdemo.controller; import java.util.List; import org.maoge.jcssmdemo.service.BlogService; import org.maoge.jcssmdemo.xdo.BlogDo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; /** * @theme 控制器--博客 * @author maoge * @date 2020-01-28 */ @RestController // 通过该注解,第一将BlogController注册为控制器,第二将其中方法返回值转换为json public class BlogController { @Autowired // 自动装配blogService private BlogService blogService; /** * 查询博客信息 1、@GetMapping表示可以使用get方法请求该api * 2、"/blog/{id}"表示请求路径为/blog/{id}的形式,其中{id}为占位符 * 3、@PathVariable("id")表示将占位符{id}的值传递给id 4、也就是说/blog/123请求的话,会将123传递给参数id */ @GetMapping(value = "/blog/{id}") public BlogDo getOne(@PathVariable("id") long id) { return blogService.getBlogById(id); } /** * 查询博客列表,使用get方法 */ @GetMapping("/blog") public List<BlogDo> getList() { return blogService.getBlogList(); } /** * 新增博客 1、@PostMapping表示使用post方法 * 2、@RequestBody表示将请求中的json信息转换为BlogDo类型的对象信息,该转换也是由SpringMVC自动完成的 */ @PostMapping("/blog") public void add(@RequestBody BlogDo blog) { blogService.addBlog(blog); } /** * 修改博客 实际上此处也可以不在路径中传递id,而是整个使用json传递对象信息,但是我查询了一些文档,貌似使用路径传递id更加规范一些,此处不用纠结 */ @PutMapping("/blog/{id}") public void update(@PathVariable("id") long id, @RequestBody BlogDo blog) { // 修改指定id的博客信息 blog.setId(id); blogService.updateBlog(blog); } /** * 删除博客 */ @DeleteMapping("/blog/{id}") public void delete(@PathVariable("id") long id) { blogService.deleteBlog(id); } }
总结
纸上得来终觉浅,绝知此事要躬行。
之前我也曾无数次看过Spring依赖注入的各种例子,但是理解始终不深刻。直到工作原因需要将一些之前xml配置的项目,改为JavaConfig+注解配置,有些需要改为SpringBoot配置。写的多了,就发现三种配置方式各有各的好处也各有缺点局限性,如果都掌握了会很有用处,起码在读别人的代码时,不管混合用了几种方式,我们都能读懂。
Spring就是通过这种灵活的组件注册,包容万象,现在实际上都成为了Java开发的事实规范了,所以可以总结一句就是:如果是搞Java开发的,对Spring花再多时间学习体会,都是超值的。
这篇关于Spring之路(35)–使用JavaConfig配置Spring+SpringMVC+MyBatis(SSM)项目完整实例的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南