SSM整合

什么是SSM整合

微观:将学习的Spring SpringMVC Mybatis框架应用到项目中!

- SpringMVC框架负责控制层

- Spring 框架负责整体和业务层的声明式事务管理

- MyBatis框架负责数据库访问层

宏观:Spring接管一切(将框架核心组件交给Spring进行IoC管理),代码更加简洁。

- SpringMVC管理表述层、SpringMVC相关组件

- Spring管理业务层、持久层、以及数据库相关(DataSource,MyBatis)的组件

- 使用IoC的方式管理一切所需组件

实施:通过编写配置文件,实现SpringIoC容器接管一切组件。

SSM核心问题明确

SSM整合需要几个IOC容器?

两个容器

web容器:装SpringMVC,Controller相关的web组件

root容器:装业务层和持久层相关的组件

好处:

1. 分离关注点

2. 解耦合

3. 灵活配置

②每个IOC容器对应那些类型组件?

SSM整合_第1张图片

|容器名

盛放组件|

|web容器

web相关组件(controller,springmvc核心组件) |

|root容器

业务和持久层相关组件(service,aop,tx,dataSource,mybatis,mapper等)|

③容器之间的关系

结论:web容器是root容器的子容器,父子容器关系。

- 父容器:root容器,盛放service、mapper、mybatis等相关组件

- 子容器:web容器,盛放controller、web相关组件

子容器可以引用父容器的组件,父容器调不了子容器

④具体多少配置类以及对应容器关系

每一层(controller;service,mapper(dao层))写一个对应配置类

1WebJavaConfig(controlller层):web相关,springmvc相关组件;

2ServiceJavaConfig(service层):业务层的扫描,aop,tx相关组件;

3MapperJavaConfig(mapper层):连接池,mybatis相关组件

初始化类

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

  //指定root容器对应的配置类

  //root容器的配置类

  @Override

  protected Class[] getRootConfigClasses() {

    return new Class[] { ServiceJavaConfig.class,MapperJavaConfig.class };

  }

  //指定web容器对应的配置类 webioc容器的配置类

  @Override

  protected Class[] getServletConfigClasses() {

    return new Class[] { WebJavaConfig.class };

  }

  //指定dispatcherServlet处理路径,通常为 /

  @Override

  protected String[] getServletMappings() {

    return new String[] { "/" };

  }

}

       需要依赖清单分析:

          spring

            ioc/di

              spring-context / 6.0.6

              jakarta.annotation-api / 2.1.1  jsr250

            aop

              spring-aspects / 6.0.6

            tx

              spring-tx  / 6.0.6

              spring-jdbc / 6.0.6

 

          springmvc

             spring-webmvc 6.0.6

             jakarta.jakartaee-web-api 9.1.0

             jackson-databind 2.15.0

             hibernate-validator / hibernate-validator-annotation-processor 8.0.0.Final

          

          mybatis

             mybatis  / 3.5.11

             mysql    / 8.0.25

             pagehelper / 5.1.11

 

          整合需要

             加载spring容器 spring-web / 6.0.6

             整合mybatis   mybatis-spring x x

             数据库连接池    druid / x

             lombok        lombok / 1.18.26

             logback       logback/ 1.2.3

控制层配置类

/**

 * 控制层的配置类(controllerspringmvc

 * 1 controller

 * 2 全局异常处理器

 *      重新写一个异常处理类

 * 3 handlerMapping handlerAdapter

 * 4 json转化器

 *      使用注解@EnableWebMvc可以自动配置34

 *

 * 5 静态资源处理

 *      重写configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)方法

 *      在方法内通过configurer调用enable()方法

 * 6 jsp 视图解析器前后缀

 *      重写configureViewResolvers(ViewResolverRegistry registry)方法

 *      在方法内通过 registry调用jsp()方法,传入前缀和后缀

 * 7 拦截器...

 *      重写addInterceptors(InterceptorRegistry registry)方法

 *      在方法内registry调用addInterceptor()方法传入拦截器类,

 *      默认是拦截所有请求的,

 *      如果想要指定拦截,可以连续调用addPathPatterns()传入handler的地址(可以模糊*

 *      如果想要排除那个,可以连续调用excludePathPatterns()方法传入要排除的handler的地址

 * 注意:该配置类可以实现WebMvcConfigurer接口,有springmvc的组件有对应的方法提供。

 */

@Configuration

@ComponentScan({"com.atguigu.controller","com.atguigu.exceptionhandler"})

@EnableWebMvc

public class WebMvcJavaConfig implements WebMvcConfigurer {

    @Override

    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {

        configurer.enable();

    }

    @Override

    public void configureViewResolvers(ViewResolverRegistry registry) {

        registry.jsp("/WEB-INF/views",".jsp");

    }

    @Override

    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(拦截器类).addPathPatterns().excludePathPatterns();

    }

}

业务层配置类

/**

 * 业务层配置类:serviceaoptx

 * 1 service

 * 2 开启aop注解的支持(@EnableAspectJAutoProxy aspect@Before @After @AfterReturning @AfterThrowing @Around @Aspect @Order

 * 3 tx开启事务声明管理(@EnableTransactionManagement)

 *             1对应的事务管理器实现 [最大接口TransactionManager 实现类:DataSourceTransactionManager Hibernate.. Jpa..]

 *                  创建一个方法,该方法返回DataSourceTransactionManager对象

 *                  注意:DataSourceTransactionManager对象需要连接池,所以在方法的形参中要有一个(DataSource dataSource)会自动引用

 *                  对象调用setDataSource()传入连接池对象

 *             2开启事务注解支持 @Transactional

 */

@Configuration

@EnableAspectJAutoProxy

@EnableTransactionManagement

public class ServiceJavaConfig {

    @Bean

    public TransactionManager transactionManager(DataSource dataSource){

        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();

        dataSourceTransactionManager.setDataSource(dataSource);//需要连接池

        return dataSourceTransactionManager;

    }

}

持久层配置类

 

主要配置mapper代理对象,连接池和mybatis核心组件配置

- 总结

    - 将SqlSessionFactory实例存储到IoC容器

    - 将Mapper实例存储到IoC容器

SqlSessionFactoryBean类:

package org.mybatis.spring

public class SqlSessionFactoryBean

    implements FactoryBean, InitializingBean, ApplicationListener {

       //封装了实例化流程

       public SqlSessionFactory getObject() throws Exception {

          if (this.sqlSessionFactory == null) {

            //实例化对象逻辑

            afterPropertiesSet();

          }

          //返回对象逻辑

          return this.sqlSessionFactory;

       }

}

mybatis整合思路总结:

- 需要将SqlSessionFactory和Mapper实例加入到IoC容器

- 使用mybatis整合包提供的FactoryBean快速整合

/**

 * 连接池的配置类

 */

@Configuration

@PropertySource("classpath:jdbc.properties")

public class DataSourceJavaConfig {

    @Value("jdbc.user")

    private String user;

    @Value("jdbc.password")

    private String password;

    @Value("jdbc.url")

    private String url;

    @Value("jdbc.diver")

    private String driver;

    @Bean

    public DataSource dataSource(){

        DruidDataSource druidDataSource = new DruidDataSource();

        druidDataSource.setUsername(user);

        druidDataSource.setPassword(password);

        druidDataSource.setUrl(url);

        druidDataSource.setDriverClassName(driver);

        return druidDataSource;

    }

}

持久层配置类方式一(不推荐)

/**

 * 持久层配置类:连接池,sqlSessionFactory,Mapper代理对象

 * 方式1:保留外部配置文件mybatis-config.xml

 * 出现的问题:如果将dataSource和mybatis的组件配置到一起,会触发@value注解不生效的问题

 *        原因:mybatis的组件优先加载,@value还没有读取!

 *        解决:分开配置,写到不同的类即可

 */

@Configuration

public class MapperJavaConfig {

    /**

     *  sqlSession加入ioc容器

     *     mybatis会提供一个 sqlSessionFactoryBean,在此工厂类的getObject方法中会完成sqlSession对象的实例化

     *  方式1 外部指定mybatis-config.xml【在此文件中,不用配置连接池,mapper指定,其他照旧】

     *

     */

    @Bean

    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){

        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        //指定配置文件等信息

        //指定数据库连接对象

        sqlSessionFactoryBean.setDataSource(dataSource);

        //指定外部的mybatis配置文件

        ClassPathResource resource = new ClassPathResource("mybatis-config.xml");

        sqlSessionFactoryBean.setConfigLocation(resource);

        return sqlSessionFactoryBean;

    }

    /**

     * mapper代理对象加入ioc

     *   mybatis也会提供一个工厂类

     *

     */

    public MapperScannerConfigurer mapperScannerConfigurer(){

        //mapper代理对象的factoryBean-》指定一个包-》mapper接口 -》sqlSession-》getMapper

        MapperScannerConfigurer mapperScannerConfigurer=new MapperScannerConfigurer();

        mapperScannerConfigurer.setBasePackage("com.atguigu.mapper");//mapper接口和mapperxml所在的共同包

        return mapperScannerConfigurer;

    }

}

持久层配置类方式二(推荐)

/**

 * 持久层配置类:连接池,sqlSessionFactory,Mapper代理对象

 * 方式2:不保留外部配置文件mybatis-config.xml  全部mybatis属性都在代码中设置!

 */

@Configuration

public class MapperJavaConfigNew {

    /**

     *  sqlSession加入ioc容器

     *     mybatis会提供一个 sqlSessionFactoryBean,在此工厂类的getObject方法中会完成sqlSession对象的实例化

     *

     */

    @Bean

    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){

        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        //指定配置文件等信息

        //指定数据库连接对象

        sqlSessionFactoryBean.setDataSource(dataSource);

**************************************************************

        //指定mybatis配置文件的功能,使用代码的形式

        org.apache.ibatis.session.Configuration configuration

                = new org.apache.ibatis.session.Configuration();

        configuration.setMapUnderscoreToCamelCase(true);

        configuration.setLogImpl(Slf4jImpl.class);

        configuration.setAutoMappingBehavior(AutoMappingBehavior.FULL);

        //org.apache.ibatis.session.Configuration 存储setting的配置文件

        sqlSessionFactoryBean.setConfiguration(configuration);

        //别名设置

        sqlSessionFactoryBean.setTypeAliasesPackage("com.atguigu.pojo");

        PageInterceptor pageInterceptor = new PageInterceptor();

        Properties properties = new Properties();

        properties.setProperty("helperDialect","mysql");

        pageInterceptor.setProperties(properties);

        sqlSessionFactoryBean.addPlugins();

        sqlSessionFactoryBean.addPlugins(pageInterceptor);

*************************************************************************

        return sqlSessionFactoryBean;

    }

    /**

     * mapper代理对象加入ioc

     *   mybatis也会提供一个工厂类

     */

    public MapperScannerConfigurer mapperScannerConfigurer(){

        //mapper代理对象的factoryBean-》指定一个包-》mapper接口 -》sqlSession-》getMapper

        MapperScannerConfigurer mapperScannerConfigurer=new MapperScannerConfigurer();

        mapperScannerConfigurer.setBasePackage("com.atguigu.mapper");//mapper接口和mapperxml所在的共同包

        return mapperScannerConfigurer;

    }

}

 配置类初始化

/**

 * ioc的初始化类(设置那个是父ioc

 */

public class SpringIocInit extends AbstractAnnotationConfigDispatcherServletInitializer {

    //rootioc容器的配置类

    @Override

    protected Class[] getRootConfigClasses() {

        return new Class[]{DataSourceJavaConfig.class, MapperJavaConfigNew.class, ServiceJavaConfig.class};

    }

    //webioc容器的配置类

    @Override

    protected Class[] getServletConfigClasses() {

        return new Class[]{WebMvcJavaConfig.class};

    }

    //dispatcherServlet的拦截路径

    @Override

    protected String[] getServletMappings() {

        return new String[]{"/"};

    }

}

前后联调与跨域问题

前后端联调:

确保前后端接口能够正常对接,数据能够正确传输的过程

前后端联调的主要内容和目的:

①接口对接

   前后端共同确认接口文档,约定数据格式(JSON/XML),确定接口调用方式和参数

②数据传输

③功能验证

④问题排查

跨域问题:

补充:浏览器遵循同源策略,要求是同源的资源才可以互相访问

同源策略:比较访问方和被访问方的域名(协议,ip,端口)三者相同就是同源,可以访问;不同就是非同源拒绝访问

前端的域名:http://127.0.0.1:5173

后端的域名:http://localhost:8080/ssm

二者是非同源的,那么如何才能让二者同源呢?

在后端修改

在后端的controller层的类上加上跨域访问的注解:

@CrossOrigin//允许其他源访问我们的controller 浏览器将不在拦截

                                                                                                                     

你可能感兴趣的:(ssm,java,开发语言)