基本的项目构建请参考:
常用方式整合SSM框架 参考了黑马程序员_吃饱就写BUG的博客-CSDN博客
的第二步
1.注解整合思路:
1.1.application-mapper.xml配置文件中配置的内容包含以下3项。
读取jdbc.properties文件中的数据连接信息并创建Druid对象,并将读取的数据连接信息注入到Druid数据连接池对象中。
<!--1. 引入属性文件配置数据源和连接池-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
创建SqlSessionFactoryBean对象,将并将Druid对象注入到SqlSessionFactoryBean对象中。
<!-- 2. 将SqlSessionFactory交给Spring托管 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" scope="singleton">
<!-- 加载数据环境 -->
<property name="dataSource" ref="dataSource"/>
<!-- 绑定mybatis配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 几乎所有的东西都能在这里面配,完全不需要mybatis的核心配置-->
</bean>
<!-- 3. 将SqlSession对象的加载交给Spring托管 -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!-- 按照mybatis的习俗,通过工厂获得SqlSession会话对象 -->
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
创建MapperScannerConfigurer对象,并指定扫描的Mapper的路径。
<!-- 4. Mapper 扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mapper"/>
</bean>
1.2.application-service.xml和spring-mvc.xml
application-service.xml配置文件中只配置了包扫描,指定需要扫描到Spring 的Service层所在的包路径。spring-mvc.xml配置文件中配置了Spring MVC扫描的包路径和注解驱动。
1.3.web.xml
web.xml配置文件配置了项目启动时加载的信息,包含如下3个内容。
使用<context-param>元素加载Spring配置文件application-service.xml和Spring整合Mybatis的配置文件application-mapper.xml
<!--配置文件加载-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-*.xml</param-value>
</context-param>
Spring容器加载监听器
<!--容器加载的监听器-->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
配置Spring MVC的前端控制器
<!--Spring MVC 前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<!--初始化参数 初始化前端控制器时加载Spring MVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--项目启动时候,初始化前端控制器-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
接下来,将项目中的XML配置文件删除,使用纯注解的配置类依次替换对应的XML文件内容,以完成纯注解的SSM框架整合。具体实现步骤如下所示。
jdbc.properties配置的数据源信息如下所示:
# 这里是数据库的配置文件,根据你自己的来配置,我只是给了一个样板
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true
&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=root
第一步:
在项目的src\main\java目录下创建路径为com.itheima.config的包,用于存放项目中的配置类。在该包中创建名称为JdbcConfig的类,用于获取数据库连接信息并定义创建数据源的对象方法,并定义getDataSource()方法,用于创建DruidDataSource对象。
package com.itheima.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
/**
* Description: 在该包中创建名称为JdbcConfig的类,用于获取数据库连接信息并定义创建数据源的对象方法,
* 并定义getDataSource()方法,用于创建DruidDataSource对象。
*/
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
@Value("${jdbc.driverClassName}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String password;
/**
* Description: 定义dataSource的bean,
* 等同于<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
*/
@Bean("dataSource")
public DataSource getDataSource() {
//创建对象
DruidDataSource ds = new DruidDataSource();
/*
等同于set属性注入<property name="driverClassName" value="driver"/>
*/
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
第二步:
在com.itheima.config包中创建名称为MyBatisConfig的类,在MyBatisConfig类中定义getSqlSessionFactoryBean()方法,用于创建SqlSessionFactoryBean对象并返回。
package com.itheima.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
/**
* @author zxd
* Description: 在MyBatisConfig类中定义getSqlSessionFactoryBean()方法,用于创建SqlSessionFactoryBean对象并返回。
*/
public class MyBatisConfig {
/**
* @author zxd
* Description: 定义MyBatis的核心连接工厂bean,
* 等同于 <bean class="org.mybatis.spring.SqlSessionFactoryBean">
* 参数使用自动装配的形式加载dataSource,
* 为set注入提供数据源,dataSource来源于JdbcConfig中的配置
*/
@Bean("sqlSessionFactoryBean")
public SqlSessionFactoryBean getSqlSessionFactoryBean(@Autowired DataSource dataSource) {
SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
//等同于<property name="dataSource" ref="dataSource"/>
ssfb.setDataSource(dataSource);
return ssfb;
}
/**
* @author zxd
* Description: 定义MyBatis的映射扫描,
* 等同于<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
*/
@Bean
public MapperScannerConfigurer getMapperScannerConfigurer() {
MapperScannerConfigurer msc = new MapperScannerConfigurer();
//等同于<property name="basePackage" value="com.itheima.dao"/>
msc.setBasePackage("com.itheima.mapper");
return msc;
}
}
第三步:
在com.itheima.config包中创建名称为SpringConfig的类作为项目定义Bean的源头,并扫描Service层对应的包。
package com.itheima.config;
import org.springframework.context.annotation.*;
/**
* @author zxd
* Description: Configuration SpringConfig的类作为项目定义Bean的源头,并扫描Service层对应的包。
* Description: @Import({MyBatisConfig.class, JdbcConfig.class}) 将MyBatisConfig类和JdbcConfig类交给Spring管理
* Description: @ComponentScan(value = "com.itheima.service") 等同于<context:component-scan base-package="com.itheima.service">
*/
@Configuration
@Import({MyBatisConfig.class, JdbcConfig.class})
@ComponentScan(value = "com.itheima.service")
public class SpringConfig {
}
第四步:
在com.itheima.config包中创建名称为SpringMvcConfig的类作为Spring MVC的配置类,在配置类中指定Controller层的扫描路径。
package com.itheima.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
/**
* @author zxd
* Description: SpringMvcConfig的类作为Spring MVC的配置类,在配置类中指定Controller层的扫描路径
*/
@Configuration
/**
* @author zxd
* Description: 等同于<context:component-scan base-package="com.itheima.controller"/>
*/
@ComponentScan("com.itheima.controller")
/**
* @author zxd
* Description: 等同于<mvc:annotation-driven/>,还不完全相同
*/
@EnableWebMvc
public class SpringMvcConfig {
}
第五步:
至此,已经完成了SSM框架整合的配置类编写,接下来需要在项目初始化Servlet容器时加载指定初始化的信息,来替代之前web.xml文件配置的信息 。在com.itheima.config包中创建名称为ServletContainersInitConfig的类,继承AbstractAnnotationConfigDispatcherServletInitializer抽象类,重写抽象类的方法。
package com.itheima.config;
import org.springframework.web.servlet.support.
AbstractAnnotationConfigDispatcherServletInitializer;
/**
* @author zxd
* Description:ServletContainersInitConfig的类,继承AbstractAnnotationConfigDispatcherServletInitializer抽象类,重写抽象类的方法。
*/
public class ServletContainersInitConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
/**
* @author zxd
* Description: 加载Spring配置类中的信息,
* 初始化Spring容器
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
/**
* @author zxd
* Description: 加载Spring MVC配置类中的信息,
* 初始化Spring MVC容器
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
/**
* @author zxd
* Description:配置DispatcherServlet的映射路径
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
重写AbstractAnnotationConfigDispatcherServletInitializer抽象类的3个方法。 getRootConfigClasses()方法:将Spring配置类的信息加载到Spring容器中。 getServletConfigClasses()方法:将Spring MVC配置类的信息加载到Spring MVC容器中。 getServletMappings()方法:可以指定DispatcherServlet的映射路径。
最后:
启动项目,在浏览器中访问图书信息查询地址,地址为http://localhost:8080/book?id=1,页面显示效果如图所示。 我的为888端口
从图中所示的信息可以看出,程序成功查询到了id为1的图书信息。表明Controller将Service获取的图书信息成功返回给页面了,由此可以得出纯注解的SSM框架整合成功
整个项目结构如图:
写在最后:
在service的实现类serviceImpl中,会报红Could not autowire. No beans of BookMapper type found. 注入失败
但是依旧可以运行并访问成功,意思是并没有对结果造成影响,但是既然出现了问题,我们就要解决这个问题
解决方法:
1、将 @Autowired
改成 @Resource
两个注解实现的功能是一样的,只是来源于不同的包而已
我采用的第一种方法!!!!!!!!!
2、将 @Autowired
改成@Autowired(required = false)
当使用@Autowired
注解的时候,其实默认为true,表示注入的时候,该bean必须存在,否则就会注入失败。所以false让它当前要注入的bean,如果有直接注入,没有跳过,不会报错
这个基于注解方式就整合完成啦