纯注解的整合方式SSM

基本的项目构建请参考:

常用方式整合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,如果有直接注入,没有跳过,不会报错

 这个基于注解方式就整合完成啦


版权声明:本文为weixin_53805188原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。