Java – 新 SSM 整合

Spring 理解

1.SpringMvc 框架中实际上是有2个IoC容器。

2.其中一个IoC容器负责承载SpringMvc中的DispatcherServlet,另一个IoC容器负责承载 Service和Mapper层的组件。

web容器 web相关组件(controller,springmvc核心组件)
root容器 业务和持久层相关组件(service,aop,tx,dataSource,mybatis,mapper等)

 

3.SpringMvc的IoC容器是另一个IoC容器的子容器。

4.在配置方面,我们可以对不同架构创建一个对应的配置类,如SpringMvc层可以创建一个专用于配置SpringMvc的配置类,其类应当被SpringMvc的IoC容器承载,而另一个父IoC容器则可以承载Service层和Mapper层的配置类。

5.在容器创建中,Spring提供了抽象类 AbstractAnnotationConfigDispatcherServletInitializer 中的三个实现方法,可以对三个不同的配置类设置到不同的IoC容器中。

public class SpringMvcInit extends AbstractAnnotationConfigDispatcherServletInitializer {

    /**
     * 用于承载父 IoC 容器配置类的加载方法
     * 在这里可以设置 Service 层与 Mapper 层的配置类
     *
     * @return
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{ServiceConfig.class, MapperConfig.class};
    }

    /**
     * 用于承载子 IoC 容器配置类的加载方法
     * 在这里可以设置 SpringMVC 的配置类
     * @return
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMVCConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

 

SSM-必要依赖

        <dependencies>
            <!--  SpringIoC容器坐标  -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>6.0.10</version>
            </dependency>
            <!--  JDBC实现  -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>6.0.10</version>
            </dependency>
            <!--  SpringMVC  -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>6.0.10</version>
            </dependency>
            <!--  Spring事务管理  -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-tx</artifactId>
                <version>6.0.10</version>
            </dependency>
            <!--  SpringAOP切面  -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>6.0.10</version>
            </dependency>
            <!--  Druid数据源  -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.2.16</version>
            </dependency>
            <!--  mysql驱动  -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.30</version>
            </dependency>
            <!--  mybatis的Spring整合包  -->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis-spring</artifactId>
                <version>2.0.7</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.10</version>
            </dependency>
            <!--  lombok  -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.28</version>
            </dependency>
            <!--  日志  -->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.4.8</version>
            </dependency>
            <!--  mybatis分页插件  -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper</artifactId>
                <version>5.2.0</version>
            </dependency>
            <!--  javax注解  -->
            <dependency>
                <groupId>jakarta.annotation</groupId>
                <artifactId>jakarta.annotation-api</artifactId>
                <version>2.1.1</version>
            </dependency>
            <!--  JSR-303 实体类参数校验实现  -->
            <dependency>
                <groupId>org.hibernate.validator</groupId>
                <artifactId>hibernate-validator</artifactId>
                <version>8.0.0.Final</version>
            </dependency>
            <dependency>
                <groupId>org.hibernate.validator</groupId>
                <artifactId>hibernate-validator-annotation-processor</artifactId>
                <version>8.0.0.Final</version>
            </dependency>
            <!--  Json数据转换  -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.78</version>
            </dependency>
        </dependencies>

 

 

 

SSM-SpringMVC配置

从上一章我们知道,SpringMvc 需要一个子IoC容器进行承载,因此我们需要对SpringMvc单独创建一个配置类,这个配置类只用于与SpringMvc有关的配置。

@Configuration
@ComponentScan(basePackages = {"cn.unsoft.controller", "cn.unsoft.exception","cn.unsoft.interceptor"})
@EnableWebMvc // 创建 handlerMapping 和 handlerAdapter 和 json 处理器
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 开启静态资源的 handlerMapping
     *
     * @param configurer
     */
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

主要有以下两个重要的操作:

 

1.创建handlerMapping 和 handlerAdapter 和Json数据处理,体现在 @EnableWebMvc 注解上。

2.对SpringMvc有关的包进行扫描,controller 包 与 exception包和  interceptor 包等

 

SSM-Service配置

Service 配置是处于root主IoC容器中,Service 中主要的配置项如声明事务管理,service层包,AOP 切面编程等

/**
 * 业务层的配置类
 * 用于配置 service aop 和 tx
 */
@Configuration
@ComponentScan(basePackages = {"cn.unsoft.service"})
@EnableTransactionManagement // 开启 声明式事务管理注解支持
@EnableAspectJAutoProxy // 开启 Aop 切面
public class ServiceConfig {

    /**
     * 配置事务管理
     * @return
     */
    @Bean
    public TransactionManager transactionManager(@Qualifier("dataSource") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }

}

Service 配置类主要做以下三个配置:

 

1.对 service 层的业务包进行扫描

2.配置声明事务管理,并开启 @Transactional 事务注解支持

3.开启AOP切面编程支持,开启后可以使用 @Before 等切面注解

 

SSM-数据源配置

我们可以使用 Druid 数据源作为Mybatis 的数据源,那么我们需要把 DruidDataSource 存入 IoC 容器中,如下代码配置DruidDataSource数据源

@Configuration
@PropertySource("classpath:jdbc.properties")
public class DataSourceConfig {
    @Bean("dataSource")
    public DataSource dataSource(@Value("${jdbc.url}") String url,
                                 @Value("${jdbc.driver}") String driver,
                                 @Value("${jdbc.username}") String username,
                                 @Value("${jdbc.password}") String password){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }
}

 特别注意:

 

DruidDataSource数据源 建议抽离到单独一个配置项中配置,因为如果DruidDataSource数据源配置在 Mybatis 配置类中的话,因Mybatis设置三方数据源方法执行时有可能早于 @Value 注解读取 properties 文件数据,导致 dataSource 方法中的形参没有及时获取数据,从而产生连接数据库失败的可能。

单独配置一个配置类,系统会把该类中所有工作做完才会操作下一步,避免抢处理顺序

 

SSM-Mybatis配置

Mapper 层的配置类应存放在Root 主IoC容器内,其主要配置的是与数据库相关的,与Mybatis 相关的配置。

首先我们要明白,Mybatis 的运行原理是使用 SqlSessionFactoryBuilder 生成 SqlSessionFactory ,再利用SqlSessionFactory创建 SqlSession的。因此 SqlSessionFactoryBuilder 不需要存入 IoC 中

那么如果我们需要把引用带到IoC容器中,本应该是把 SqlSession 存到IoC容器中的,但是SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。

因此我们不能直接把 SqlSession 存到IoC容器中,而是把 SqlSessionFactory 存到IoC容器中动态生成不同线程的SqlSession。

mapper映射器是使用 SqlSession.getMapper() 获取到的,通常我们可以在IoC容器中获取mapper映射器,但是但是从使用的角度来说,业务类(service)需要注入mapper接口,所以mapper应该交给ioc容器管理!

最终我们得出结论,SqlSessionFactory 和 mapper 接口应该存到IoC容器中。 

 

把SqlSessionFactory存到容器中

我们可以通过手动的方式把SqlSessionFactory存到IoC容器中,如下代码:

@Bean
public SqlSessionFactory sqlSessionFactory(){
   //1.读取外部配置文件
  InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");
  
  //2.创建sqlSessionFactory
  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);
  
  return sqlSessionFactory;
}

但是我们不推荐自己创建SqlSessionFactory存入IoC中。

 

为了提高整合效率,mybatis提供了提供封装SqlSessionFactory和Mapper实例化的逻辑的FactoryBean组件,我们只需要声明和指定少量的配置即可!该类存在 mybatis-spring 包中。

我们使用 SqlSessionFactoryBean 创建 SqlSessionFactory 并存入 IoC容器中。

 

依赖xml配置的 SqlSessionFactory

若我们的项目中,mybatis 依然使用 xml 作为配置项的话,我们可以把 mybatis-config.xml 配置项文件在创建 SqlSessionFactoryBean 后载入,其配置就可以写在 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>
    <settings>
        <!-- 开启驼峰式映射-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
        <!-- 开启logback日志输出-->
        <setting name="logImpl" value="SLF4J"/>
        <!--开启resultMap自动映射 -->
        <setting name="autoMappingBehavior" value="FULL"/>
    </settings>

    <typeAliases>
        <!-- 给实体类起别名 -->
        <package name="com.atguigu.pojo"/>
    </typeAliases>

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!--
                helperDialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。
                你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:
                oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby
                (完整内容看 PageAutoDialect) 特别注意:使用 SqlServer2012 数据库时,
                https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md#%E5%A6%82%E4%BD%95%E9%85%8D%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93%E6%96%B9%E8%A8%80
             -->
            <property name="helperDialect" value="mysql"/>
        </plugin>
    </plugins>
</configuration>

 

/**
 * 保留 Mybatis-config.xml 配置文件方式整合 Mybatis
 */
@Configuration
@ComponentScan("cn.unsoft.mapper")
public class MapperConfig {


    /**
     * 把 SqlSessionFactory 存入 IoC 容器中
     * @param dataSource
     * @return
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        Resource resource = new ClassPathResource("mybatis-config.xml");
        sqlSessionFactoryBean.setConfigLocation(resource);
        return sqlSessionFactoryBean;
    }

    /**
     * 对所有 mapper 接口 使用 SqlSession.getMapper() 获取代理对象
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("cn.unsoft.mapper");
        return mapperScannerConfigurer;
    }
}

 

 

不依赖xml 配置 SqlSessionFactory

若我们不希望再使用 mybatis-config.xml 文件配置mybatis 时,我们可以在 SqlSessionFactory 中配置与 xml 文件相同的各种设置,这样我们就可以不需要 xml 文件了。代码如下:

/**
 * 不保留 Mybatis-config.xml 文件的方式整命 Mybatis
 * 所有在 xml 文件中配置的配置项全部使用代码代替
 */
@Configuration
@ComponentScan("cn.unsoft.mapper")
public class MapperConfig {

    /**
     * 创建 SqlSessionFactoryBean 同时配置 Mybatis
     *
     * @param dataSource
     * @return
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        /**
         * 设置第三方数据源
         */
        sqlSessionFactoryBean.setDataSource(dataSource);
        /**
         * 设置配置项
         * 1.配置驼峰映射功能
         * 2.配置深层映射功能
         * 3.配置日志输出实现类
         */
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setLogImpl(Log4j2Impl.class);
        configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL);
        sqlSessionFactoryBean.setConfiguration(configuration);
        /**
         * 配置mapper接口位置
         */
        sqlSessionFactoryBean.setTypeAliasesPackage("cn.unsoft.mapper");


        /**
         * 配置分页插件
         */
        PageInterceptor pageInterceptor = new PageInterceptor();
        /**
         * 配置分页使用的数据库方言
         */
        Properties properties = new Properties();
        properties.setProperty("helperDialect", "mysql");
        pageInterceptor.setProperties(properties);
        
        sqlSessionFactoryBean.setPlugins(pageInterceptor);

        return sqlSessionFactoryBean;
    }

    /**
     * mapper代理对象加入到ioc容器中
     *
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("cn.unsoft.mapper");
        return mapperScannerConfigurer;
    }
}

 

 

配置mapper代理对象到 IoC 容器中

使用 MapperScannerConfigurer 类对所有mapper接口进行生成代理对象,并存到 IoC容器中。

    /**
     * mapper代理对象加入到ioc容器中
     *
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("cn.unsoft.mapper");
        return mapperScannerConfigurer;
    }

 

 

SSM-初始化容器启动配置

我们完成了 SpringMvc、Service、Mybatis三个层级的架构配置项后,就需要对这些配置项配置在DispatherServlet 启动时创建 IoC 容器后执行的启动操作类中。

前面我们说过,启动时创建 IoC 容器后 会执行 AbstractAnnotationConfigDispatcherServletInitializer 类,这个类将要求提供SpringMVC的配置类作为子IoC容器,和Root主IoC容器。

我们可以把 SpringMvc 、 Service、 Mybatis 这三个配置类配置到对应的IoC容器中:

/**
 * Spring 启动类
 */
public class SpringInit extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * root Ioc 容器指定配置类
     *
     * @return
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{DataSourceConfig.class, ServiceConfig.class, MapperConfigNew.class};
    }

    /**
     * WebMvc Ioc 容器指定配置类
     *
     * @return
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebMvcConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}

其中,getServletConfigClasses 则是配置子 IoC 容器的方法,我们把SpringMvc配置类加载进去,DataSourceConfig.class, ServiceConfig.class, MapperConfigNew.class这三个配置类则加载到 Root 主 IoC容器中去。

致此,SpringMvc启动后会把这些配置项都加载到对应的 IoC 容器中去。

 

前后端分离跨域问题

跨域问题只能由后端进行配置。

如果目前使用的是SpringMvc基础框架搭建的Web程序,我们只需要在Controller 上加上注解 @CrossOrigin 即可开启跨域访问

@RestController
@CrossOrigin
@RequestMapping("/xxx")
public class ScheduleController { ... }

 

也可以在SpringMvc配置项中增加 CORS 匹配策略:

@Configuration
@EnableWebMvc // 创建 handlerMapping 和 handlerAdapter 和 json 处理器
public class WebMvcConfig implements WebMvcConfigurer {

    /**
     * 增加所有请求都允许使用CORS跨域请求
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").
        // 设置允许跨域请求的域名
        .allowedOriginPatterns("*")
        // 是否允许cookie
        .allowCredentials(true)
        // 设置允许的请求方式
        .allowedMethods("GET", "POST", "DELETE", "PUT")
        // 设置允许的header属性
        .allowedHeaders("*")
        // 跨域允许时间
        .maxAge(3600);
    }
}

 

如果使用的是 Spring Security 框架,请参考 Spring Security 的相关CORS跨域配置。

 

项目下载

https://www.tzming.com/wp-content/uploads/2023/filesdown/SSM.rar

 

如果您喜欢本站,点击这儿不花一分钱捐赠本站

这些信息可能会帮助到你: 下载帮助 | 报毒说明 | 进站必看

修改版本安卓软件,加群提示为修改者自留,非本站信息,注意鉴别

THE END
分享
二维码
打赏
海报
Java – 新 SSM 整合
Spring 理解 1.SpringMvc 框架中实际上是有2个IoC容器。 2.其中一个IoC容器负责承载SpringMvc中的DispatcherServlet,另一个IoC容器负责承载 Service和Mapper层的组件。 web容器 we……
<<上一篇
下一篇>>