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容器中找)