和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(全局共享)))
<!--系统初始化参数(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容器中找)