这是一个问题,问很多人都不清楚的问题,也许有一部分人知道spring是隐式得调用DefaultLisTableBeanFactory的父类AbstractBeanFactory的
getBean()方法来真正实例化对象的,那么,这个getBean()到底是在什么地方调用的呢?
getBean()方法来真正实例化对象的,那么,这个getBean()到底是在什么地方调用的呢?
那么,我们就来分析一下吧。
1:基于springMVC框架的项目:
这个就很简单了,我们都知道基于spring的web项目。IOC容器初始化的入口全部在l里面:
<listener-class>
org.t.ContextLoaderListener
</listener-class>
</listener>
通过这个ContextLoaderListener,spring完成了BeanDefinition的解析,注册。也就是完成了对XML配置文件的解读,并把所有定义的bean
<listener-class>
org.t.ContextLoaderListener
</listener-class>
</listener>
通过这个ContextLoaderListener,spring完成了BeanDefinition的解析,注册。也就是完成了对XML配置文件的解读,并把所有定义的bean
信息作为spring特有的数据结构存储到了BeanDefinition集合。并将这个集合作为hasMap保存在容器里。并且在这个过程中,建立了web项目的上下
文环境。
接下来,我们看springMvc的容器初始化,他是通过l的这个入口进入的。通过这个DispatcherServlet的入口,spring会再次建立一个上下
文在DispatcherServlet建立起来的上下文之上的。
<servlet>
<servlet-name>tms</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>tms</servlet-name>
文环境。
接下来,我们看springMvc的容器初始化,他是通过l的这个入口进入的。通过这个DispatcherServlet的入口,spring会再次建立一个上下
文在DispatcherServlet建立起来的上下文之上的。
<servlet>
<servlet-name>tms</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>tms</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
好了,接下来的事情就很明显了,项目启动起来后,当一个URL请求过来的时候,就会进入 DispatcherServlet,在这个类里面,spring调用了
getBean()方法,对URL请求需要用到的对象,都进行了实例化。
我们可以看看通常我们的一个控制层的配置文件:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "/dtd/spring-beans-2.0.dtd">
<beans>
</servlet-mapping>
好了,接下来的事情就很明显了,项目启动起来后,当一个URL请求过来的时候,就会进入 DispatcherServlet,在这个类里面,spring调用了
getBean()方法,对URL请求需要用到的对象,都进行了实例化。
我们可以看看通常我们的一个控制层的配置文件:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="suggestCompletedController" class="cn.s.controller.SuggestCompletedController">
<property name="methodNameResolver">
<bean class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/xtGetSuggestData.htm">getSuggestData</prop>
</props>
</property>
</bean>
</property>
<property name="baseService" ref="baseService" />
<property name="suggestCompletedService" ref="suggestCompletedService"/>
<property name="methodNameResolver">
<bean class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver">
<property name="mappings">
<props>
<prop key="/xtGetSuggestData.htm">getSuggestData</prop>
</props>
</property>
</bean>
</property>
<property name="baseService" ref="baseService" />
<property name="suggestCompletedService" ref="suggestCompletedService"/>
</bean>
<bean id="mbUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/yunxingList.htm">sjjEhrController</prop>
<prop key="/getSjxByLeixingList.htm">sjjEhrController</prop>
<prop key="/yxkSjxEdit.htm">sjjEhrController</prop>
</props>
</property>
</bean>
<bean id="mbUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/yunxingList.htm">sjjEhrController</prop>
<prop key="/getSjxByLeixingList.htm">sjjEhrController</prop>
<prop key="/yxkSjxEdit.htm">sjjEhrController</prop>
</props>
</property>
</bean>
</beans>
可以看到,控制层的所有bean定义都是需要被注入到 mbUrlMapping里面的。
我们接下来看看DispatcherServlet。他有很多init方法,其中就有一个initHandlerMappings:
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null;
if (this.detectAllHandlerMappings) {
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());
// We keep HandlerMappings in sorted order.
OrderComparator.sort(this.handlerMappings);
}
}
else {
try {
HandlerMapping hm = Bean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerMapping later.
}
}
OrderComparator.sort(this.handlerMappings);
}
}
else {
try {
HandlerMapping hm = Bean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
this.handlerMappings = Collections.singletonList(hm);
}
catch (NoSuchBeanDefinitionException ex) {
// Ignore, we'll add a default HandlerMapping later.
}
}
// Ensure we have at least one HandlerMapping, by registering
// a default HandlerMapping if no other mappings are found.
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if (logger.isDebugEnabled()) {
logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
}
}
}
也就是在这个地方,spring显式的调用了
HandlerMapping hm = Bean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
来完成了对象的初始化工作。
if (this.handlerMappings == null) {
this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
if (logger.isDebugEnabled()) {
logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");
}
}
}
也就是在这个地方,spring显式的调用了
HandlerMapping hm = Bean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
来完成了对象的初始化工作。
至于为什么会来调用这个方法,是因为spring dispatcherServlet集成了httpServlet。WEB容器会自动调用他的
init()方法,这个init放在在他的父类:HttpServletBean做了实现:
public final void init() throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet '" + getServletName() + "'");
}
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet '" + getServletName() + "'");
}
// Set bean properties from init parameters.
try {
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), quiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
try {
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), quiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
&isterCustomEditor(Resource.class, new ResourceEditor(resourceLoader, vironment));
initBeanWrapper(bw); bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
&("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
实例化类和实例化对象 throw ex;
}
initBeanWrapper(bw); bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
&("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
实例化类和实例化对象 throw ex;
}
// Let subclasses do whatever initialization they like.
initServletBean(); //这里会调用一个初始化
initServletBean(); //这里会调用一个初始化
if (logger.isDebugEnabled()) {
logger.debug("Servlet '" + getServletName() + "' configured successfully");
}
}
logger.debug("Servlet '" + getServletName() + "' configured successfully");
}
}
//initServletBean方法
protected final void initServletBean() throws ServletException {
getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");
if (this.logger.isInfoEnabled()) {
this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");
}
long startTime = System.currentTimeMillis();
protected final void initServletBean() throws ServletException {
getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");
if (this.logger.isInfoEnabled()) {
this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");
}
long startTime = System.currentTimeMillis();
try {
this.webApplicationContext = initWebApplicationContext(); //这里进入
initFrameworkServlet();
}
catch (ServletException ex) {
("Context initialization failed", ex);
throw ex;
this.webApplicationContext = initWebApplicationContext(); //这里进入
initFrameworkServlet();
}
catch (ServletException ex) {
("Context initialization failed", ex);
throw ex;
}
catch (RuntimeException ex) {
("Context initialization failed", ex);
throw ex;
}
catch (RuntimeException ex) {
("Context initialization failed", ex);
throw ex;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论