Spring----整合web和整合spring mvc

spring和web整合

分析

  当我们学习 java web,进行一些简单的页面操作,也可以通过jdbc和数据库打交道

  然后我们学习了spring,我们就可以将创建对象的权利交给了spring,spring创建对象的时候,自动注入属性

  然后我们就可以直接将jave web和spring整合到一起了,当我们访问url,请求到来,在post或者get方法中,我们就可以new ClassPathXmlApplicationContext("springContext.xml"),然后获得spring容器,并从容器中获得对象。

  但是我们发现,如果每次new ClassPathXmlApplicationContext("springContext.xml"),就会出现多个spring容器,并且这样的性能也会出现很大的问题。

  于是我们有想出了新的解决方案:tomcat启动,自动创建spring容器,我们每次只需要获取这个spring容器即可。

  

pom.xml

添加依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.17.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.3.17.RELEASE</version>
        </dependency>

注:spring-web依赖spring-beans和spring-core,如果spring-web的版本过高,此时他依赖的还是spring-context中的spring-beans和spring-core的版本,而忽略的自己spring-web中的spring-beans版本。

原因是此时的spring-context放在了spring-web前面,如果把它们放的顺序反过来,依赖的包又不一样了。

web.xml

  (使用监听器,在服务器启动的时候加载配置文件,生成一个spring容器(存放在ServletContext(全局共享)))

  ContextLoaderListener监听器:

  会读取这些XML文件并产生WebApplicationContext对象,然后将这个对象放置在ServletContext的属性里,这样只要我们得到Servlet就可以得到WebApplicationContext对象,并利用这个对象访问spring容器管理的bean。

<!--系统初始化参数(ServletContext初始化参数):确定xml文件位置-->
<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-context*.xml</param-value>
    </context-param>
<!--配置监听器,如果没有配置上面的xml文件位置,默认找的xml文件是/WEB-INF/applicationContext.xml-->
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

 

web中

spring-context.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:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:annotation-config />
    <context:component-scan base-package="com.funtl.my.shop.web.admin">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!-- 配置 Bean Validator 定义 -->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
    <bean id="beanValidator" class="com.funtl.my.shop.commons.validator.BeanValidator">
        <property name="validator" ref="validator" />
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 开启事务注解驱动 -->
    <tx:annotation-driven transaction-manager="transactionManager" />
</beans>

  

  

使用:了解即可(以后我们采用框架整和)

结合我的另一篇博客的综合示例:https://www.cnblogs.com/yanxiaoge/p/10964372.html

@WebServlet("/test")
public class Controller extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //之前这样写,我们每一次都需要重新加载配置文件
        ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-context.xml");
        UserAcountService user = (UserAcountService) appContext.getBean("userAcountServiceImpl");


        //现在我们直接让服务器启动的时候,就加载配置文件,如果我们spring容器,就直接获取就可以了(这样就不需要反复的new ClassPathXmlApplicationContext)
        //手动获取spring容器,方式1:
        ApplicationContext applicationContext = (ApplicationContext) this.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
        UserAcountService userAcountService = (UserAcountService) applicationContext.getBean("userAcountServiceImpl");
        //使用工具获得spring容器,方式2:
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        Object xx = webApplicationContext.getBean("xx");

        //获取容器后,从容器中拿的对象;
        userAcountService.transfer("渣渣辉","古天乐",10);
        resp.getWriter().write("ok");
    }
}

  

和spring mvc 整合

前言:有了spring MVC IOC容器,是否需要加spring ioc容器?(是否需要在web.xml中配置启动spring IOC容器的ContextLoaderListener)

观点:

  1.需要:通常情况下,类似于数据源,事务,整合其他框架都是放在Spring的配置文件中(而不是放在SpringMVC的配置文件中)。实际上放入Spring配置文件对应的IOC容器中的还有Service和Dao。

  2.不需要:都放在SpringMVC的配置文件中。也可以分多个Spring的配置文件,在spring-MVC.xml 中使用import节点导入其他的配置文件,或者直接在web.xml 使用通配符导入所有的配置。

观点1:如果我们需要单独一个spring IOC容器的话。spring和spring MVC如何整和?

使用监听器(上面有代码)

但是会出现问题:如果spring IOC容器和spring MVC IOC容器扫描的包包含重合的部分,就会导致bean被创建两次;

  解决:让这两个包不要都扫描同一个注解,使用<context:exclude-filter> 和 <context:include-filter>

 

spring MVC IOC容器和spring IOC容器的联系?

  Spring MVC的IOC 容器中的bean 可以来引用Spring IOC容器中的bean(简单点就是spring MVC没有扫描的bean可以去spring IOC容器中去拿),返回来呢?反之则不行。Spring IOC容器中的bean 却不能来用 SpringMVC IOC容器中的bean!(个人理解(纯粹瞎猜):监听器优先启动,读取spring IOC容器加载读取配置文件,依赖注入,但是,如果注入的bean没有的话,就会报错,而spring MVC IOC容器,后启动,如果注入的bean没有的话,可以去spring IOC容器中找)

  

 

posted @ 2019-05-07 18:23  小名的同学  阅读(709)  评论(0编辑  收藏  举报