Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
Spring_resource_analysis
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
WeifengSun
Spring_resource_analysis
Commits
2574ac2c
Commit
2574ac2c
authored
Oct 05, 2022
by
SunWei峰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
初识Spring MVC
parent
8b079d43
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
63 additions
and
7 deletions
+63
-7
spring-framework-main/README.md
+11
-7
spring-framework-main/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java
+6
-0
spring-framework-main/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java
+2
-0
spring-framework-main/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
+25
-0
spring-framework-main/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java
+12
-0
spring-framework-main/spring-webmvc/src/main/java/org/springframework/web/servlet/HttpServletBean.java
+7
-0
No files found.
spring-framework-main/README.md
View file @
2574ac2c
# Spring源码分析
# Spring源码分析
***
***
> 说明: 个人学习 Spring 源码,仅供自己学习使用,其中不以任何方式谋取利益,
> 说明: <br>
> 有需要的同学们可以自行下载。
> 个人学习 Spring 源码,仅供自己学习使用,其中不以任何方式谋取利益。<br>
> 学习过程可能引用到某些博客中的信息,书籍中的信息。
> 未对源码做任何修改,只是在学习时加入自己理解的注解(部分参照网络博客)。<br>
> 如果涉嫌侵权,请联系本人立即删除。
> 有需要的同学们可以自行拉取。<br>
> 学习过程可能引用到某些博客中的信息,书籍中的信息。<br>
> 如果涉嫌侵权,请联系本人立即删除。<br>
> 如有需要某些资源(不违反任何规定情况下)可联系我给大家分享。<br>
`联系邮箱`
:
`osfung@163.com`
`联系邮箱`
:
`osfung@163.com`
...
@@ -12,6 +14,8 @@
...
@@ -12,6 +14,8 @@
源码获取方式:github 官方获取
源码获取方式:github 官方获取
源码地址:https://github.com/spring-projects/spring-framework
Spring版本:6.0.0
Spring版本:6.0.0
Java版本:JDK17
Java版本:JDK 17
\ No newline at end of file
\ No newline at end of file
spring-framework-main/spring-web/src/main/java/org/springframework/web/context/ContextLoader.java
View file @
2574ac2c
...
@@ -257,6 +257,8 @@ public class ContextLoader {
...
@@ -257,6 +257,8 @@ public class ContextLoader {
* @see #CONFIG_LOCATION_PARAM
* @see #CONFIG_LOCATION_PARAM
*/
*/
public
WebApplicationContext
initWebApplicationContext
(
ServletContext
servletContext
)
{
public
WebApplicationContext
initWebApplicationContext
(
ServletContext
servletContext
)
{
// 初始化完成的 webApplicationContext 会被保存到 servletContext 的属性中,key 为 ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
// 所以这里是判断是否已经初始化了webApplicationContext,就抛出异常(web.xml 中声明了多次ContextLoader 的定义),不可重复初始化。
if
(
servletContext
.
getAttribute
(
WebApplicationContext
.
ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
)
!=
null
)
{
if
(
servletContext
.
getAttribute
(
WebApplicationContext
.
ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
)
!=
null
)
{
throw
new
IllegalStateException
(
throw
new
IllegalStateException
(
"Cannot initialize context because there is already a root application context present - "
+
"Cannot initialize context because there is already a root application context present - "
+
...
@@ -289,6 +291,7 @@ public class ContextLoader {
...
@@ -289,6 +291,7 @@ public class ContextLoader {
}
}
servletContext
.
setAttribute
(
WebApplicationContext
.
ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
,
this
.
context
);
servletContext
.
setAttribute
(
WebApplicationContext
.
ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
,
this
.
context
);
// 映射当前的类加载器 与 创建的实例到全局变量 currentContextPerThread 中。
ClassLoader
ccl
=
Thread
.
currentThread
().
getContextClassLoader
();
ClassLoader
ccl
=
Thread
.
currentThread
().
getContextClassLoader
();
if
(
ccl
==
ContextLoader
.
class
.
getClassLoader
())
{
if
(
ccl
==
ContextLoader
.
class
.
getClassLoader
())
{
currentContext
=
this
.
context
;
currentContext
=
this
.
context
;
...
@@ -341,6 +344,7 @@ public class ContextLoader {
...
@@ -341,6 +344,7 @@ public class ContextLoader {
* @see org.springframework.web.context.support.XmlWebApplicationContext
* @see org.springframework.web.context.support.XmlWebApplicationContext
*/
*/
protected
Class
<?>
determineContextClass
(
ServletContext
servletContext
)
{
protected
Class
<?>
determineContextClass
(
ServletContext
servletContext
)
{
// 获取 contextClassName。第一次初始化自然是没有缓存的
String
contextClassName
=
servletContext
.
getInitParameter
(
CONTEXT_CLASS_PARAM
);
String
contextClassName
=
servletContext
.
getInitParameter
(
CONTEXT_CLASS_PARAM
);
if
(
contextClassName
!=
null
)
{
if
(
contextClassName
!=
null
)
{
try
{
try
{
...
@@ -352,6 +356,8 @@ public class ContextLoader {
...
@@ -352,6 +356,8 @@ public class ContextLoader {
}
}
}
}
else
{
else
{
// 默认策略获取 contextClassName。通过上面的静态代码块我们可以知道defaultStrategies 读取的是 ContextLoader.properties 文件中的内容
// 默认是 XmlWebApplicationContext
contextClassName
=
defaultStrategies
.
getProperty
(
WebApplicationContext
.
class
.
getName
());
contextClassName
=
defaultStrategies
.
getProperty
(
WebApplicationContext
.
class
.
getName
());
try
{
try
{
return
ClassUtils
.
forName
(
contextClassName
,
ContextLoader
.
class
.
getClassLoader
());
return
ClassUtils
.
forName
(
contextClassName
,
ContextLoader
.
class
.
getClassLoader
());
...
...
spring-framework-main/spring-web/src/main/java/org/springframework/web/context/ContextLoaderListener.java
View file @
2574ac2c
...
@@ -94,6 +94,8 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte
...
@@ -94,6 +94,8 @@ public class ContextLoaderListener extends ContextLoader implements ServletConte
}
}
// 容器启动时会调用
// TODO: 2022/10/5 contextInitialized 在这儿
/**
/**
* Initialize the root web application context.
* Initialize the root web application context.
*/
*/
...
...
spring-framework-main/spring-webmvc/src/main/java/org/springframework/web/servlet/DispatcherServlet.java
View file @
2574ac2c
...
@@ -160,6 +160,7 @@ import org.springframework.web.util.WebUtils;
...
@@ -160,6 +160,7 @@ import org.springframework.web.util.WebUtils;
* @see org.springframework.web.servlet.mvc.Controller
* @see org.springframework.web.servlet.mvc.Controller
* @see org.springframework.web.context.ContextLoaderListener
* @see org.springframework.web.context.ContextLoaderListener
*/
*/
// DispatcherServlet 在这儿,init() 方法在父类 HttpServletBean 中
@SuppressWarnings
(
"serial"
)
@SuppressWarnings
(
"serial"
)
public
class
DispatcherServlet
extends
FrameworkServlet
{
public
class
DispatcherServlet
extends
FrameworkServlet
{
...
@@ -492,14 +493,23 @@ public class DispatcherServlet extends FrameworkServlet {
...
@@ -492,14 +493,23 @@ public class DispatcherServlet extends FrameworkServlet {
* <p>May be overridden in subclasses in order to initialize further strategy objects.
* <p>May be overridden in subclasses in order to initialize further strategy objects.
*/
*/
protected
void
initStrategies
(
ApplicationContext
context
)
{
protected
void
initStrategies
(
ApplicationContext
context
)
{
// 初始化多文件上传解析器
initMultipartResolver
(
context
);
initMultipartResolver
(
context
);
// 初始化国际化解析器
initLocaleResolver
(
context
);
initLocaleResolver
(
context
);
// 初始化主题解析器
initThemeResolver
(
context
);
initThemeResolver
(
context
);
// 初始化 HandlerMapping
initHandlerMappings
(
context
);
initHandlerMappings
(
context
);
// 初始化 HandlerAdapter
initHandlerAdapters
(
context
);
initHandlerAdapters
(
context
);
// 初始化 Handler异常解析器
initHandlerExceptionResolvers
(
context
);
initHandlerExceptionResolvers
(
context
);
// 初始化RequestToViewNameTranslator
initRequestToViewNameTranslator
(
context
);
initRequestToViewNameTranslator
(
context
);
// 初始化 视图解析器
initViewResolvers
(
context
);
initViewResolvers
(
context
);
// 初始化 FlashMapManager
initFlashMapManager
(
context
);
initFlashMapManager
(
context
);
}
}
...
@@ -509,6 +519,10 @@ public class DispatcherServlet extends FrameworkServlet {
...
@@ -509,6 +519,10 @@ public class DispatcherServlet extends FrameworkServlet {
* no multipart handling is provided.
* no multipart handling is provided.
*/
*/
private
void
initMultipartResolver
(
ApplicationContext
context
)
{
private
void
initMultipartResolver
(
ApplicationContext
context
)
{
// 在 Spring 中,MultipartResolver 主要用来处理文件上传。默认情况下,Spring是没有 Multipart 处理的。
// 如果想使用 Spring 的 Multipart,则需要手动注入 Multipart 解析器,即MultipartResolver。
// 这样Spring 会检查每个请求是否包含 Multipart,如果包含,那么 MultipartResolver 就会解析它。
// 一般我们可以注入 CommonsMultipartResolver。
try
{
try
{
this
.
multipartResolver
=
context
.
getBean
(
MULTIPART_RESOLVER_BEAN_NAME
,
MultipartResolver
.
class
);
this
.
multipartResolver
=
context
.
getBean
(
MULTIPART_RESOLVER_BEAN_NAME
,
MultipartResolver
.
class
);
if
(
logger
.
isTraceEnabled
())
{
if
(
logger
.
isTraceEnabled
())
{
...
@@ -533,6 +547,7 @@ public class DispatcherServlet extends FrameworkServlet {
...
@@ -533,6 +547,7 @@ public class DispatcherServlet extends FrameworkServlet {
* we default to AcceptHeaderLocaleResolver.
* we default to AcceptHeaderLocaleResolver.
*/
*/
private
void
initLocaleResolver
(
ApplicationContext
context
)
{
private
void
initLocaleResolver
(
ApplicationContext
context
)
{
// 一共有三种实现类,一种使用 URL 后缀类型,一种基于 cookie 实现,一种基于 session 来实现
try
{
try
{
this
.
localeResolver
=
context
.
getBean
(
LOCALE_RESOLVER_BEAN_NAME
,
LocaleResolver
.
class
);
this
.
localeResolver
=
context
.
getBean
(
LOCALE_RESOLVER_BEAN_NAME
,
LocaleResolver
.
class
);
if
(
logger
.
isTraceEnabled
())
{
if
(
logger
.
isTraceEnabled
())
{
...
@@ -558,6 +573,7 @@ public class DispatcherServlet extends FrameworkServlet {
...
@@ -558,6 +573,7 @@ public class DispatcherServlet extends FrameworkServlet {
* we default to a FixedThemeResolver.
* we default to a FixedThemeResolver.
*/
*/
private
void
initThemeResolver
(
ApplicationContext
context
)
{
private
void
initThemeResolver
(
ApplicationContext
context
)
{
// 通过主题来改变用户体验,三种实现类:固定主题、主题保存在 session 中、主题保存在 cookie 中。
try
{
try
{
this
.
themeResolver
=
context
.
getBean
(
THEME_RESOLVER_BEAN_NAME
,
ThemeResolver
.
class
);
this
.
themeResolver
=
context
.
getBean
(
THEME_RESOLVER_BEAN_NAME
,
ThemeResolver
.
class
);
if
(
logger
.
isTraceEnabled
())
{
if
(
logger
.
isTraceEnabled
())
{
...
@@ -583,19 +599,24 @@ public class DispatcherServlet extends FrameworkServlet {
...
@@ -583,19 +599,24 @@ public class DispatcherServlet extends FrameworkServlet {
* we default to BeanNameUrlHandlerMapping.
* we default to BeanNameUrlHandlerMapping.
*/
*/
private
void
initHandlerMappings
(
ApplicationContext
context
)
{
private
void
initHandlerMappings
(
ApplicationContext
context
)
{
// 映射器可以有多个,在选用时会进行优先级排序,依次调用映射器链,找到就会直接返回处理器路径。
this
.
handlerMappings
=
null
;
this
.
handlerMappings
=
null
;
// 如果启用所有的HandlerMapping。可以通过这个参数来控制是使用指定的HandlerMapping,还是检索所有的
if
(
this
.
detectAllHandlerMappings
)
{
if
(
this
.
detectAllHandlerMappings
)
{
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
// 寻找所有的 HandlerMapping 类型的类
Map
<
String
,
HandlerMapping
>
matchingBeans
=
Map
<
String
,
HandlerMapping
>
matchingBeans
=
BeanFactoryUtils
.
beansOfTypeIncludingAncestors
(
context
,
HandlerMapping
.
class
,
true
,
false
);
BeanFactoryUtils
.
beansOfTypeIncludingAncestors
(
context
,
HandlerMapping
.
class
,
true
,
false
);
if
(!
matchingBeans
.
isEmpty
())
{
if
(!
matchingBeans
.
isEmpty
())
{
this
.
handlerMappings
=
new
ArrayList
<>(
matchingBeans
.
values
());
this
.
handlerMappings
=
new
ArrayList
<>(
matchingBeans
.
values
());
// We keep HandlerMappings in sorted order.
// We keep HandlerMappings in sorted order.
// 按照优先级进行排序
AnnotationAwareOrderComparator
.
sort
(
this
.
handlerMappings
);
AnnotationAwareOrderComparator
.
sort
(
this
.
handlerMappings
);
}
}
}
}
else
{
else
{
// 如果使用指定的参数,从容器中获取 beanName 为 "handlerMapping" 的 HandlerMapping
try
{
try
{
HandlerMapping
hm
=
context
.
getBean
(
HANDLER_MAPPING_BEAN_NAME
,
HandlerMapping
.
class
);
HandlerMapping
hm
=
context
.
getBean
(
HANDLER_MAPPING_BEAN_NAME
,
HandlerMapping
.
class
);
this
.
handlerMappings
=
Collections
.
singletonList
(
hm
);
this
.
handlerMappings
=
Collections
.
singletonList
(
hm
);
...
@@ -607,6 +628,7 @@ public class DispatcherServlet extends FrameworkServlet {
...
@@ -607,6 +628,7 @@ public class DispatcherServlet extends FrameworkServlet {
// Ensure we have at least one HandlerMapping, by registering
// Ensure we have at least one HandlerMapping, by registering
// a default HandlerMapping if no other mappings are found.
// a default HandlerMapping if no other mappings are found.
// 如果 handlerMappings 为null。则使用默认策略指定的HandlerMapping
if
(
this
.
handlerMappings
==
null
)
{
if
(
this
.
handlerMappings
==
null
)
{
this
.
handlerMappings
=
getDefaultStrategies
(
context
,
HandlerMapping
.
class
);
this
.
handlerMappings
=
getDefaultStrategies
(
context
,
HandlerMapping
.
class
);
if
(
logger
.
isTraceEnabled
())
{
if
(
logger
.
isTraceEnabled
())
{
...
@@ -870,8 +892,11 @@ public class DispatcherServlet extends FrameworkServlet {
...
@@ -870,8 +892,11 @@ public class DispatcherServlet extends FrameworkServlet {
}
}
}
}
// 获取Name
String
key
=
strategyInterface
.
getName
();
String
key
=
strategyInterface
.
getName
();
// 从配置文件中获取 value
String
value
=
defaultStrategies
.
getProperty
(
key
);
String
value
=
defaultStrategies
.
getProperty
(
key
);
// 获取到 value 之后就是对 value 的处理,添加返回。
if
(
value
!=
null
)
{
if
(
value
!=
null
)
{
String
[]
classNames
=
StringUtils
.
commaDelimitedListToStringArray
(
value
);
String
[]
classNames
=
StringUtils
.
commaDelimitedListToStringArray
(
value
);
List
<
T
>
strategies
=
new
ArrayList
<>(
classNames
.
length
);
List
<
T
>
strategies
=
new
ArrayList
<>(
classNames
.
length
);
...
...
spring-framework-main/spring-webmvc/src/main/java/org/springframework/web/servlet/FrameworkServlet.java
View file @
2574ac2c
...
@@ -528,7 +528,9 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
...
@@ -528,7 +528,9 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
long
startTime
=
System
.
currentTimeMillis
();
long
startTime
=
System
.
currentTimeMillis
();
try
{
try
{
// 委托给 initWebApplicationContext 方法来完成进一步的初始化
this
.
webApplicationContext
=
initWebApplicationContext
();
this
.
webApplicationContext
=
initWebApplicationContext
();
// 留给子类覆盖操作
initFrameworkServlet
();
initFrameworkServlet
();
}
}
catch
(
ServletException
|
RuntimeException
ex
)
{
catch
(
ServletException
|
RuntimeException
ex
)
{
...
@@ -563,6 +565,7 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
...
@@ -563,6 +565,7 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
WebApplicationContextUtils
.
getWebApplicationContext
(
getServletContext
());
WebApplicationContextUtils
.
getWebApplicationContext
(
getServletContext
());
WebApplicationContext
wac
=
null
;
WebApplicationContext
wac
=
null
;
// 1. 如果 webApplicationContext 在构造函数的时候被注入,则 wac != null, 则可以直接使用
if
(
this
.
webApplicationContext
!=
null
)
{
if
(
this
.
webApplicationContext
!=
null
)
{
// A context instance was injected at construction time -> use it
// A context instance was injected at construction time -> use it
wac
=
this
.
webApplicationContext
;
wac
=
this
.
webApplicationContext
;
...
@@ -574,9 +577,11 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
...
@@ -574,9 +577,11 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
// the root application context (if any; may be null) as the parent
// the root application context (if any; may be null) as the parent
cwac
.
setParent
(
rootContext
);
cwac
.
setParent
(
rootContext
);
}
}
// 2.刷新上下文环境
configureAndRefreshWebApplicationContext
(
cwac
);
configureAndRefreshWebApplicationContext
(
cwac
);
}
}
}
}
// 3. 如果构造函数并没有注入,则wac为null,根据 contextAttribute 属性加载 WebApplicationContext
if
(
wac
==
null
)
{
if
(
wac
==
null
)
{
// No context instance was injected at construction time -> see if one
// No context instance was injected at construction time -> see if one
// has been registered in the servlet context. If one exists, it is assumed
// has been registered in the servlet context. If one exists, it is assumed
...
@@ -584,8 +589,10 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
...
@@ -584,8 +589,10 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
// user has performed any initialization such as setting the context id
// user has performed any initialization such as setting the context id
wac
=
findWebApplicationContext
();
wac
=
findWebApplicationContext
();
}
}
// 4. 如果上面两个方式都没有加载到 WebApplicationContext,则尝试自己加载
if
(
wac
==
null
)
{
if
(
wac
==
null
)
{
// No context instance is defined for this servlet -> create a local one
// No context instance is defined for this servlet -> create a local one
// 自己尝试创建WebApplicationContext
wac
=
createWebApplicationContext
(
rootContext
);
wac
=
createWebApplicationContext
(
rootContext
);
}
}
...
@@ -594,6 +601,7 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
...
@@ -594,6 +601,7 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
// support or the context injected at construction time had already been
// support or the context injected at construction time had already been
// refreshed -> trigger initial onRefresh manually here.
// refreshed -> trigger initial onRefresh manually here.
synchronized
(
this
.
onRefreshMonitor
)
{
synchronized
(
this
.
onRefreshMonitor
)
{
// 5.刷新
onRefresh
(
wac
);
onRefresh
(
wac
);
}
}
}
}
...
@@ -659,15 +667,18 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
...
@@ -659,15 +667,18 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
wac
.
setEnvironment
(
getEnvironment
());
wac
.
setEnvironment
(
getEnvironment
());
wac
.
setParent
(
parent
);
wac
.
setParent
(
parent
);
// 获取web.xml 配置的 DispatcherServlet init-params contextConfigLocation 属性
String
configLocation
=
getContextConfigLocation
();
String
configLocation
=
getContextConfigLocation
();
if
(
configLocation
!=
null
)
{
if
(
configLocation
!=
null
)
{
wac
.
setConfigLocation
(
configLocation
);
wac
.
setConfigLocation
(
configLocation
);
}
}
// 配置 WebApplicationContext 实例并刷新
configureAndRefreshWebApplicationContext
(
wac
);
configureAndRefreshWebApplicationContext
(
wac
);
return
wac
;
return
wac
;
}
}
// 已经创建的 WebApplicationContext 实例进行配置及刷新。其实就是配置并刷新Spring。
protected
void
configureAndRefreshWebApplicationContext
(
ConfigurableWebApplicationContext
wac
)
{
protected
void
configureAndRefreshWebApplicationContext
(
ConfigurableWebApplicationContext
wac
)
{
if
(
ObjectUtils
.
identityToString
(
wac
).
equals
(
wac
.
getId
()))
{
if
(
ObjectUtils
.
identityToString
(
wac
).
equals
(
wac
.
getId
()))
{
// The application context id is still set to its original default value
// The application context id is still set to its original default value
...
@@ -682,6 +693,7 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
...
@@ -682,6 +693,7 @@ public abstract class FrameworkServlet extends HttpServletBean implements Applic
}
}
}
}
// 设置一些属性,ServletContext、ServletConfig等
wac
.
setServletContext
(
getServletContext
());
wac
.
setServletContext
(
getServletContext
());
wac
.
setServletConfig
(
getServletConfig
());
wac
.
setServletConfig
(
getServletConfig
());
wac
.
setNamespace
(
getNamespace
());
wac
.
setNamespace
(
getNamespace
());
...
...
spring-framework-main/spring-webmvc/src/main/java/org/springframework/web/servlet/HttpServletBean.java
View file @
2574ac2c
...
@@ -148,12 +148,16 @@ public abstract class HttpServletBean extends HttpServlet implements Environment
...
@@ -148,12 +148,16 @@ public abstract class HttpServletBean extends HttpServlet implements Environment
public
final
void
init
()
throws
ServletException
{
public
final
void
init
()
throws
ServletException
{
// Set bean properties from init parameters.
// Set bean properties from init parameters.
// 1. 封装及验证初始化参数
PropertyValues
pvs
=
new
ServletConfigPropertyValues
(
getServletConfig
(),
this
.
requiredProperties
);
PropertyValues
pvs
=
new
ServletConfigPropertyValues
(
getServletConfig
(),
this
.
requiredProperties
);
if
(!
pvs
.
isEmpty
())
{
if
(!
pvs
.
isEmpty
())
{
try
{
try
{
// 2. 将当前 Servlet 实例转化为 BeanWrapper 实例
BeanWrapper
bw
=
PropertyAccessorFactory
.
forBeanPropertyAccess
(
this
);
BeanWrapper
bw
=
PropertyAccessorFactory
.
forBeanPropertyAccess
(
this
);
// 3. 注册于相对于 Resource 的属性编辑器
ResourceLoader
resourceLoader
=
new
ServletContextResourceLoader
(
getServletContext
());
ResourceLoader
resourceLoader
=
new
ServletContextResourceLoader
(
getServletContext
());
bw
.
registerCustomEditor
(
Resource
.
class
,
new
ResourceEditor
(
resourceLoader
,
getEnvironment
()));
bw
.
registerCustomEditor
(
Resource
.
class
,
new
ResourceEditor
(
resourceLoader
,
getEnvironment
()));
// 4. 属性注入(支持 Spring 的自动注入)
initBeanWrapper
(
bw
);
initBeanWrapper
(
bw
);
bw
.
setPropertyValues
(
pvs
,
true
);
bw
.
setPropertyValues
(
pvs
,
true
);
}
}
...
@@ -166,6 +170,7 @@ public abstract class HttpServletBean extends HttpServlet implements Environment
...
@@ -166,6 +170,7 @@ public abstract class HttpServletBean extends HttpServlet implements Environment
}
}
// Let subclasses do whatever initialization they like.
// Let subclasses do whatever initialization they like.
// 5. servletBean的初始化
initServletBean
();
initServletBean
();
}
}
...
@@ -220,10 +225,12 @@ public abstract class HttpServletBean extends HttpServlet implements Environment
...
@@ -220,10 +225,12 @@ public abstract class HttpServletBean extends HttpServlet implements Environment
Set
<
String
>
missingProps
=
(!
CollectionUtils
.
isEmpty
(
requiredProperties
)
?
Set
<
String
>
missingProps
=
(!
CollectionUtils
.
isEmpty
(
requiredProperties
)
?
new
HashSet
<>(
requiredProperties
)
:
null
);
new
HashSet
<>(
requiredProperties
)
:
null
);
// 获取 web.xml 中 DispatcherServlet 配置的 init-params 属性内容
Enumeration
<
String
>
paramNames
=
config
.
getInitParameterNames
();
Enumeration
<
String
>
paramNames
=
config
.
getInitParameterNames
();
while
(
paramNames
.
hasMoreElements
())
{
while
(
paramNames
.
hasMoreElements
())
{
String
property
=
paramNames
.
nextElement
();
String
property
=
paramNames
.
nextElement
();
Object
value
=
config
.
getInitParameter
(
property
);
Object
value
=
config
.
getInitParameter
(
property
);
// 保存 init-params 属性
addPropertyValue
(
new
PropertyValue
(
property
,
value
));
addPropertyValue
(
new
PropertyValue
(
property
,
value
));
if
(
missingProps
!=
null
)
{
if
(
missingProps
!=
null
)
{
missingProps
.
remove
(
property
);
missingProps
.
remove
(
property
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment