SpringMVC
controller的安全性
-
controller
是线程不安全的 -
避免不安全的方法:
-
尽量不在
controller
中使用成员变量 -
使用
prototype
这种形式的,此种方法存在缺点:创建太多实例,回收交给用户。 -
使用
threadLocal
-
SpringMVC的启动方式
web.xml + 监听器
-
文件存在的意义:
web.xml
这个文件是必须的,web容器启动之后,会从web.xml
中读取内容, -
web.xml
中数据的读取次序:-
context-param
配置参数,用于
webApplicationContext
的参数构建。 -
listener
-
配置
ContextLoaderListener
,在这里边配置监听器, -
作用:监听到web容器启动的事件,会调用监听器的
contextInitialized
方法,初始化出来一个WebApplicationContext
,WebApplicationContext
会根据web.xml
中的context-param
,加载对应配置文件中的bean,这个上下文会初始化出上传解析器,处理器映射器,适配器,异常处理器,视图解析器等等内容。
-
-
filter
-
servlet
:配置并初始化dispatcherServlet
,这个dispatcherServlet
里面的方法,是初始化处理器映射器,处理器适配器,视图解析器等DispatcherServlet
作为控制器层的入口,依赖于WebApplicationContext
提供的 Bean 来处理请求。WebApplicationContext
提供的 Bean 包含DispatcherServlet 需要的所有 Spring Bean,包括控制器、视图解析器、拦截器等。
-
-
xml内容
-
web.xml内容
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <display-name>SpringWebApp</display-name> <!-- 配置 Spring 的 ContextLoaderListener --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置 Spring 的 DispatcherServlet --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <!-- 在这里指定dispatcherServlet的配置文件的位置 --> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcherServlet-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
applicationContext.xml内容
注,applicationContext.xml中可以配置userService,也可以放到一个专门的配置文件中,事务相关的配置也可以放到专门的位置。
<?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"> <!-- 配置数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mydatabase"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> <!-- 配置 UserService bean --> <bean id="userService" class="com.example.UserService"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 声明式事务管理配置 --> <tx:annotation-driven/> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> </beans>
注:要使用userService中的dataSource,可以使用下面的两种方式:
-
set属性注入的方式:
package com.example; import javax.sql.DataSource; public class UserService { private DataSource dataSource; // 设置 dataSource 的 setter 方法 public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } // 其他业务方法... }
<bean id="userService" class="com.example.UserService"> <property name="dataSource" ref="dataSource"/> </bean>
-
构造方法注入:
package com.example; import javax.sql.DataSource; public class UserService { private DataSource dataSource; // 构造函数注入 dataSource public UserService(DataSource dataSource) { this.dataSource = dataSource; } // 其他业务方法... }
<bean id="userService" class="com.example.UserService"> <constructor-arg ref="dataSource"/> </bean>
-
-
dispatcherServlet-servlet.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:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 配置控制器 --> <bean class="com.example.MyController"/> <!-- 配置视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 配置拦截器 --> <mvc:interceptors> <bean class="com.example.MyInterceptor"/> </mvc:interceptors> </beans>
-
使用ServletContainerInitializer接口启动(不使用web.xml)
-
ServletContainerInitializer
属于servlet3.0规范,允许框架和库在Servlet容器启动的时候动态地进行注册servlet,Filter,Listener等初始化操作。
使用
ServletContainerInitializer
接口,就可以在onStartup()
方法中初始化dispatcherServlet
了,而不用再使用复杂的web.xml方式进行监听,配置了。 -
WebApplicationInitializer
如果使用spring框架来配置和管理web应用程序,通常情况下只需要实现
WebApplicationInitializer
接口即可,无需直接使用ServletContainerInitializer
。在servlet容器启动时配置spring应用程序的上下文和组件,Spring框架会负责将开发者实现的
WebApplicationInitializer
接口的实现类,自动注册到servlet容器中,并且在启动时调用它的onStartUp()
方法。注:Spring有个类
SpringServletContainerInitializer
,是用来读取所有的WebApplicationInitializer
,本身并不实现业务。public class MyWebAppInitializer implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { // 创建 AnnotationConfigWebApplicationContext,并注册配置类 AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); context.register(AppConfig.class); // AppConfig 是你的 Spring MVC 配置类 // 创建并注册 DispatcherServlet DispatcherServlet dispatcherServlet = new DispatcherServlet(context); ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", dispatcherServlet); registration.setLoadOnStartup(1); registration.addMapping("/"); // 如果需要,你也可以注册其他的 Servlet、Filter、Listener 等等 } }