- 浏览: 981192 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
一般在web应用配置Spring上下文如下,那么ContextLoaderListener到底做了什么呢,我们来看一下
//上下文加载监听器
//上下文加载器
//抽象应用上下文
//AbstractRefreshableApplicationContext
//默认bean容器
//bean配置处理器
//bean配置解析
//扫描组件注解配置解析器
//ClassPathBeanDefinitionScanner,bean定义扫描
//Servlet上下文监听器
//上下文配置文件资源
//属性配置文件加载工具
//Properties
//ServletContextEvent
//ApplicationContext
//WebApplicationContext
//ConfigurableWebApplicationContext
//StandardServletEnvironment
//WebApplicationContext工具类
//ApplicationContextInitializer
//bean工具类
总结:
Spring上下文加载监听,在静态语句块中加载配置文件contextConfigLocation,
然后初始化ServletContext,以便spring容器可以直接访问web容器上下文,注册bean后置处理器,构造bean,初始化消息源,监听器;在构造bean的过程中通过ConfigurationClassParser来解析bean,处理注解,IOC等。
如果有哪位大哥知道,请务必不吝赐教!
这是很早写的一篇文章,都忘的差不多了,加载父类代码为
Spring Web MVC是依赖于Spring环境的定义的,而每一个Spring环境可以最多有一个父环境的引用。
http://blog.csdn.net/robertleepeak/article/details/5891750
如果有哪位大哥知道,请务必不吝赐教!
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/ApplicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> ruid/*</url-pattern> </web-app>
//上下文加载监听器
public class ContextLoaderListener extends ContextLoader implements ServletContextListener { public ContextLoaderListener(WebApplicationContext context) { super(context); } public void contextInitialized(ServletContextEvent event) { //初始化WebApplicationContext initWebApplicationContext(event.getServletContext()); } public void contextDestroyed(ServletContextEvent event) { closeWebApplicationContext(event.getServletContext()); ContextCleanupListener.cleanupAttributes(event.getServletContext()); } }
//上下文加载器
public class ContextLoader { public ContextLoader(WebApplicationContext context) { this.context = context; } public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { Log logger; long startTime; //如果servletContext的WebApplicationContext.root属性存在,则抛出根应用上下文已经初始化异常 if(servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) throw new IllegalStateException("Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!"); logger = LogFactory.getLog(org/springframework/web/context/ContextLoader); servletContext.log("Initializing Spring root WebApplicationContext"); if(logger.isInfoEnabled()) logger.info("Root WebApplicationContext: initialization started"); startTime = System.currentTimeMillis(); if(context == null) context = createWebApplicationContext(servletContext); if(context instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)context; if(!cwac.isActive()) { if(cwac.getParent() == null) { //加载应用上下文 ApplicationContext parent = loadParentContext(servletContext); //设置web上下文的父上下文 cwac.setParent(parent); } //设置并刷新WebApplicationContext configureAndRefreshWebApplicationContext(cwac, servletContext); } } //设置WebApplicationContext的root属性 servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, context); ClassLoader ccl = Thread.currentThread().getContextClassLoader(); if(ccl == org/springframework/web/context/ContextLoader.getClassLoader()) currentContext = context; else if(ccl != null) //设置当前线程的上下文 currentContextPerThread.put(ccl, context); if(logger.isDebugEnabled()) logger.debug((new StringBuilder()).append("Published root WebApplicationContext as ServletContext attribute with name [").append(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).append("]").toString()); if(logger.isInfoEnabled()) { long elapsedTime = System.currentTimeMillis() - startTime; logger.info((new StringBuilder()).append("Root WebApplicationContext: initialization completed in ").append(elapsedTime).append(" ms").toString()); } return context; RuntimeException ex; ex; logger.error("Context initialization failed", ex); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex); throw ex; Error err; err; logger.error("Context initialization failed", err); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err); throw err; } //创建WebApplicationContext protected WebApplicationContext createWebApplicationContext(ServletContext sc) { Class contextClass = determineContextClass(sc); if(!org/springframework/web/context/ConfigurableWebApplicationContext.isAssignableFrom(contextClass)) throw new ApplicationContextException((new StringBuilder()).append("Custom context class [").append(contextClass.getName()).append("] is not of type [").append(org/springframework/web/context/ConfigurableWebApplicationContext.getName()).append("]").toString()); else return (ConfigurableWebApplicationContext)BeanUtils.instantiateClass(contextClass); } //获取ContextClass protected Class determineContextClass(ServletContext servletContext) { String contextClassName; contextClassName = servletContext.getInitParameter("contextClass"); if(contextClassName == null) break MISSING_BLOCK_LABEL_55; return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader()); throw new ApplicationContextException((new StringBuilder()).append("Failed to load custom context class [").append(contextClassName).append("]").toString(), ex); contextClassName = defaultStrategies.getProperty(org/springframework/web/context/WebApplicationContext.getName()); return ClassUtils.forName(contextClassName, org/springframework/web/context/ContextLoader.getClassLoader()); throw new ApplicationContextException((new StringBuilder()).append("Failed to load default context class [").append(contextClassName).append("]").toString(), ex); } //加载应用上下文 protected ApplicationContext loadParentContext(ServletContext servletContext) { ApplicationContext parentContext = null; String locatorFactorySelector = servletContext.getInitParameter("locatorFactorySelector"); String parentContextKey = servletContext.getInitParameter("parentContextKey"); if(parentContextKey != null) { BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); Log logger = LogFactory.getLog(org/springframework/web/context/ContextLoader); if(logger.isDebugEnabled()) logger.debug((new StringBuilder()).append("Getting parent context definition: using parent context key of '").append(parentContextKey).append("' with BeanFactoryLocator").toString()); parentContextRef = locator.useBeanFactory(parentContextKey); //获取父应用上下文 parentContext = (ApplicationContext)parentContextRef.getFactory(); } return parentContext; } //设置并刷新WebApplicationContext protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { if(ObjectUtils.identityToString(wac).equals(wac.getId())) { String idParam = sc.getInitParameter("contextId"); if(idParam != null) wac.setId(idParam); else wac.setId((new StringBuilder()).append(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX).append(ObjectUtils.getDisplayString(sc.getContextPath())).toString()); } //设置web上下文的ServletContext wac.setServletContext(sc); //获取上下文位置 String configLocationParam = sc.getInitParameter("contextConfigLocation"); if(configLocationParam != null) wac.setConfigLocation(configLocationParam); ConfigurableEnvironment env = wac.getEnvironment(); if(env instanceof ConfigurableWebEnvironment) ((ConfigurableWebEnvironment)env).initPropertySources(sc, null); customizeContext(sc, wac); //bean容器初始化,关键 wac.refresh(); } protected void customizeContext(ServletContext sc, ConfigurableWebApplicationContext wac) { List initializerClasses = determineContextInitializerClasses(sc); if(initializerClasses.isEmpty()) return; ArrayList initializerInstances = new ArrayList(); Class initializerClass; for(Iterator iterator = initializerClasses.iterator(); iterator.hasNext(); initializerInstances.add(BeanUtils.instantiateClass(initializerClass))) { initializerClass = (Class)iterator.next(); //解决初始化类,类型问题 Class initializerContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass, org/springframework/context/ApplicationContextInitializer); if(initializerContextClass != null) Assert.isAssignable(initializerContextClass, wac.getClass(), String.format("Could not add context initializer [%s] since its generic parameter [%s] is not assignable from the type of application context used by this context loader [%s]: ", new Object[] { initializerClass.getName(), initializerContextClass.getName(), wac.getClass().getName() })); } AnnotationAwareOrderComparator.sort(initializerInstances); ApplicationContextInitializer initializer; for(Iterator iterator1 = initializerInstances.iterator(); iterator1.hasNext(); initializer.initialize(wac)) initializer = (ApplicationContextInitializer)iterator1.next(); } //获取需要上下文需要初始化的类 protected List determineContextInitializerClasses(ServletContext servletContext) { List classes = new ArrayList(); String globalClassNames = servletContext.getInitParameter("globalInitializerClasses"); if(globalClassNames != null) { String as[] = StringUtils.tokenizeToStringArray(globalClassNames, ",; \t\n"); int i = as.length; for(int j = 0; j < i; j++) { String className = as[j]; classes.add(loadInitializerClass(className)); } } String localClassNames = servletContext.getInitParameter("contextInitializerClasses"); if(localClassNames != null) { String as1[] = StringUtils.tokenizeToStringArray(localClassNames, ",; \t\n"); int k = as1.length; for(int l = 0; l < k; l++) { String className = as1[l]; classes.add(loadInitializerClass(className)); } } return classes; } //根据className获取需要加载的Class private Class loadInitializerClass(String className) { Class clazz; clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader()); Assert.isAssignable(org/springframework/context/ApplicationContextInitializer, clazz); return clazz; ClassNotFoundException ex; ex; throw new ApplicationContextException((new StringBuilder()).append("Failed to load context initializer class [").append(className).append("]").toString(), ex); } public static final String CONTEXT_ID_PARAM = "contextId"; public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation"; public static final String CONTEXT_CLASS_PARAM = "contextClass"; public static final String CONTEXT_INITIALIZER_CLASSES_PARAM = "contextInitializerClasses"; public static final String GLOBAL_INITIALIZER_CLASSES_PARAM = "globalInitializerClasses"; public static final String LOCATOR_FACTORY_SELECTOR_PARAM = "locatorFactorySelector"; public static final String LOCATOR_FACTORY_KEY_PARAM = "parentContextKey"; private static final String INIT_PARAM_DELIMITERS = ",; \t\n"; private static final String DEFAULT_STRATEGIES_PATH = "ContextLoader.properties"; private static final Properties defaultStrategies; private static final Map currentContextPerThread = new ConcurrentHashMap(1); private static volatile WebApplicationContext currentContext; private WebApplicationContext context;//web应用上下恩 private BeanFactoryReference parentContextRef;//父上下文的bean工厂引用 static { try { //创建上下文配置文件资源 ClassPathResource resource = new ClassPathResource("ContextLoader.properties", org/springframework/web/context/ContextLoader); //加载上下文配置文件 defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch(IOException ex) { throw new IllegalStateException((new StringBuilder()).append("Could not load 'ContextLoader.properties': ").append(ex.getMessage()).toString()); } } }
//抽象应用上下文
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext, DisposableBean { public AbstractApplicationContext() { logger = LogFactory.getLog(getClass()); id = ObjectUtils.identityToString(this); displayName = ObjectUtils.identityToString(this); beanFactoryPostProcessors = new ArrayList(); active = false; closed = false; activeMonitor = new Object(); startupShutdownMonitor = new Object(); applicationListeners = new LinkedHashSet(); resourcePatternResolver = getResourcePatternResolver(); } public AbstractApplicationContext(ApplicationContext parent) { this(); setParent(parent); } //设置父应用上下文 public void setParent(ApplicationContext parent) { this.parent = parent; if(parent != null) { Environment parentEnvironment = parent.getEnvironment(); if(parentEnvironment instanceof ConfigurableEnvironment) getEnvironment().merge((ConfigurableEnvironment)parentEnvironment); } } public void refresh() throws BeansException, IllegalStateException { synchronized(startupShutdownMonitor) { //准备刷新 prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //bean容器准备工作 prepareBeanFactory(beanFactory); try { //bean后置处理器配置 postProcessBeanFactory(beanFactory); //bean容器解析构造bean,关键 invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); //初始化消息源 initMessageSource(); initApplicationEventMulticaster(); onRefresh(); //注册应用监听器 registerListeners(); //初始化bean容器 finishBeanFactoryInitialization(beanFactory); finishRefresh(); } catch(BeansException ex) { destroyBeans(); cancelRefresh(ex); throw ex; } } } //准备刷新 protected void prepareRefresh() { startupDate = System.currentTimeMillis(); synchronized(activeMonitor) { active = true; } if(logger.isInfoEnabled()) logger.info((new StringBuilder()).append("Refreshing ").append(this).toString()); //初始化属性员 initPropertySources(); //校验必须的属性 getEnvironment().validateRequiredProperties(); } protected void initPropertySources() { } //获取ConfigurableListableBeanFactory protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if(logger.isDebugEnabled()) logger.debug((new StringBuilder()).append("Bean factory for ").append(getDisplayName()).append(": ").append(beanFactory).toString()); return beanFactory; } //获取内部父bean容器 protected BeanFactory getInternalParentBeanFactory() { return ((BeanFactory) ((getParent() instanceof ConfigurableApplicationContext) ? ((ConfigurableApplicationContext)getParent()).getBeanFactory() : getParent())); } //bean容器准备工作 protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //bean容器类加载器 beanFactory.setBeanClassLoader(getClassLoader()); //bean容器Expression解决器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //添加bean后置处理器 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(org/springframework/context/ResourceLoaderAware); beanFactory.ignoreDependencyInterface(org/springframework/context/ApplicationEventPublisherAware); beanFactory.ignoreDependencyInterface(org/springframework/context/MessageSourceAware); beanFactory.ignoreDependencyInterface(org/springframework/context/ApplicationContextAware); beanFactory.ignoreDependencyInterface(org/springframework/context/EnvironmentAware); beanFactory.registerResolvableDependency(org/springframework/beans/factory/BeanFactory, beanFactory); beanFactory.registerResolvableDependency(org/springframework/core/io/ResourceLoader, this); beanFactory.registerResolvableDependency(org/springframework/context/ApplicationEventPublisher, this); beanFactory.registerResolvableDependency(org/springframework/context/ApplicationContext, this); if(beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } if(!beanFactory.containsLocalBean("environment")) beanFactory.registerSingleton("environment", getEnvironment()); if(!beanFactory.containsLocalBean("systemProperties")) beanFactory.registerSingleton("systemProperties", getEnvironment().getSystemProperties()); if(!beanFactory.containsLocalBean("systemEnvironment")) beanFactory.registerSingleton("systemEnvironment", getEnvironment().getSystemEnvironment()); } //bean后置处理器配置 protected void postProcessBeanFactory(ConfigurableListableBeanFactory configurablelistablebeanfactory) { } //bean容器解析构造bean protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); } //初始化消息源 protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if(beanFactory.containsLocalBean("messageSource")) { messageSource = (MessageSource)beanFactory.getBean("messageSource", org/springframework/context/MessageSource); if(parent != null && (messageSource instanceof HierarchicalMessageSource)) { HierarchicalMessageSource hms = (HierarchicalMessageSource)messageSource; if(hms.getParentMessageSource() == null) hms.setParentMessageSource(getInternalParentMessageSource()); } if(logger.isDebugEnabled()) logger.debug((new StringBuilder()).append("Using MessageSource [").append(messageSource).append("]").toString()); } else { DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); messageSource = dms; beanFactory.registerSingleton("messageSource", messageSource); if(logger.isDebugEnabled()) logger.debug((new StringBuilder()).append("Unable to locate MessageSource with name 'messageSource': using default [").append(messageSource).append("]").toString()); } } protected void onRefresh() throws BeansException { } //注册应用监听器 protected void registerListeners() { ApplicationListener listener; for(Iterator iterator = getApplicationListeners().iterator(); iterator.hasNext(); getApplicationEventMulticaster().addApplicationListener(listener)) listener = (ApplicationListener)iterator.next(); String listenerBeanNames[] = getBeanNamesForType(org/springframework/context/ApplicationListener, true, false); String as[] = listenerBeanNames; int i = as.length; for(int j = 0; j < i; j++) { String lisName = as[j]; getApplicationEventMulticaster().addApplicationListenerBean(lisName); } } //初始化bean容器 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { if(beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", org/springframework/core/convert/ConversionService)) beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", org/springframework/core/convert/ConversionService)); String weaverAwareNames[] = beanFactory.getBeanNamesForType(org/springframework/context/weaving/LoadTimeWeaverAware, false, false); String as[] = weaverAwareNames; int i = as.length; for(int j = 0; j < i; j++) { String weaverAwareName = as[j]; getBean(weaverAwareName); } beanFactory.setTempClassLoader(null); beanFactory.freezeConfiguration(); beanFactory.preInstantiateSingletons(); } public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource"; public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor"; public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster"; protected final Log logger; private String id; private String displayName; private ApplicationContext parent; private final List beanFactoryPostProcessors;//bean后置处理器 private long startupDate; private boolean active; private boolean closed; private final Object activeMonitor;//激活同步监控锁 private final Object startupShutdownMonitor;//启动关闭同步监控锁 private Thread shutdownHook; private ResourcePatternResolver resourcePatternResolver;//资源解决其 private LifecycleProcessor lifecycleProcessor; private MessageSource messageSource;//国际化消息处理 private ApplicationEventMulticaster applicationEventMulticaster; private Set applicationListeners; private ConfigurableEnvironment environment; static { org/springframework/context/event/ContextClosedEvent.getName(); } }
//AbstractRefreshableApplicationContext
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext { //刷新bean容器 protected final void refreshBeanFactory() throws BeansException { if(hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { //创建bean容器 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //定制bean容器 customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized(beanFactoryMonitor) { this.beanFactory = beanFactory; } } } //创建bean容器 protected DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(getInternalParentBeanFactory()); } //定制bean容器 protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { if(allowBeanDefinitionOverriding != null) beanFactory.setAllowBeanDefinitionOverriding(allowBeanDefinitionOverriding.booleanValue()); if(allowCircularReferences != null) //是否允许环路引用 beanFactory.setAllowCircularReferences(allowCircularReferences.booleanValue()); } //加载bean容器定义 protected abstract void loadBeanDefinitions(DefaultListableBeanFactory defaultlistablebeanfactory) throws BeansException, IOException; private Boolean allowBeanDefinitionOverriding; private Boolean allowCircularReferences; private DefaultListableBeanFactory beanFactory; private final Object beanFactoryMonitor; }
//默认bean容器
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { private static Class javaxInjectProviderClass = null; private static final Map serializableFactories = new ConcurrentHashMap(8); private String serializationId; private boolean allowBeanDefinitionOverriding; private boolean allowEagerClassLoading; private Comparator dependencyComparator; private AutowireCandidateResolver autowireCandidateResolver; private final Map resolvableDependencies; private final Map beanDefinitionMap;//bean定义 private final Map allBeanNamesByType; private final Map singletonBeanNamesByType;//单例bean private final List beanDefinitionNames;//beanNames,List private boolean configurationFrozen; private String frozenBeanDefinitionNames[]; static { try { javaxInjectProviderClass = ClassUtils.forName("javax.inject.Provider", org/springframework/beans/factory/support/DefaultListableBeanFactory.getClassLoader()); } } } //bean注册代理 class PostProcessorRegistrationDelegate { public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) { Set processedBeans = new HashSet(); if(beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory; List regularPostProcessors = new LinkedList(); List registryPostProcessors = new LinkedList(); for(Iterator iterator = beanFactoryPostProcessors.iterator(); iterator.hasNext();) { BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)iterator.next(); if(postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor; registryPostProcessor.postProcessBeanDefinitionRegistry(registry); registryPostProcessors.add(registryPostProcessor); } else { regularPostProcessors.add(postProcessor); } } for(boolean reiterate = true; reiterate;) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(org/springframework/beans/factory/support/BeanDefinitionRegistryPostProcessor, true, false); String as3[] = postProcessorNames; int k1 = as3.length; int l1 = 0; while(l1 < k1) { String ppName = as3[l1]; if(!processedBeans.contains(ppName)) { BeanDefinitionRegistryPostProcessor pp = (BeanDefinitionRegistryPostProcessor)beanFactory.getBean(ppName, org/springframework/beans/factory/support/BeanDefinitionRegistryPostProcessor); registryPostProcessors.add(pp); processedBeans.add(ppName); //注册bean,关键在这 pp.postProcessBeanDefinitionRegistry(registry); reiterate = true; } l1++; } } } }
//bean配置处理器
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware { public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { if(factoriesPostProcessed.contains(Integer.valueOf(registryId))) { throw new IllegalStateException((new StringBuilder()).append("postProcessBeanFactory already called for this post-processor against ").append(registry).toString()); } else { //处理bean的定义 processConfigBeanDefinitions(registry); } } public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { Set configCandidates = new LinkedHashSet(); String as[] = registry.getBeanDefinitionNames(); int i = as.length; for(int j = 0; j < i; j++) { String beanName = as[j]; BeanDefinition beanDef = registry.getBeanDefinition(beanName); if(ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, metadataReaderFactory)) configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } ConfigurationClassParser parser = new ConfigurationClassParser(metadataReaderFactory, problemReporter, environment, resourceLoader, componentScanBeanNameGenerator, registry); //根据bean配置,解析bean parser.parse(configCandidates); parser.validate(); } }
//bean配置解析
class ConfigurationClassParser { public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory, ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader, BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry) { this.metadataReaderFactory = metadataReaderFactory; this.problemReporter = problemReporter; this.environment = environment; this.resourceLoader = resourceLoader; this.registry = registry; //组件注解扫面解析器 componentScanParser = new ComponentScanAnnotationParser(resourceLoader, environment, componentScanBeanNameGenerator, registry); conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader); } //根据bean配置,解析bean public void parse(Set configCandidates) { for(Iterator iterator = configCandidates.iterator(); iterator.hasNext();) { BeanDefinitionHolder holder = (BeanDefinitionHolder)iterator.next(); BeanDefinition bd = holder.getBeanDefinition(); try { if((bd instanceof AbstractBeanDefinition) && ((AbstractBeanDefinition)bd).hasBeanClass()) parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName()); else parse(bd.getBeanClassName(), holder.getBeanName()); } } } protected final void parse(String className, String beanName) throws IOException { MetadataReader reader = metadataReaderFactory.getMetadataReader(className); processConfigurationClass(new ConfigurationClass(reader, beanName)); } }
//扫描组件注解配置解析器
class ComponentScanAnnotationParser { public ComponentScanAnnotationParser(ResourceLoader resourceLoader, Environment environment, BeanNameGenerator beanNameGenerator, BeanDefinitionRegistry registry) { this.resourceLoader = resourceLoader; this.environment = environment; this.beanNameGenerator = beanNameGenerator; this.registry = registry; } //解析注解配置 public Set parse(AnnotationAttributes componentScan, String declaringClass) { ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, componentScan.getBoolean("useDefaultFilters")); Assert.notNull(environment, "Environment must not be null"); scanner.setEnvironment(environment); Assert.notNull(resourceLoader, "ResourceLoader must not be null"); scanner.setResourceLoader(resourceLoader); Class generatorClass = componentScan.getClass("nameGenerator"); boolean useInheritedGenerator = org/springframework/beans/factory/support/BeanNameGenerator.equals(generatorClass); scanner.setBeanNameGenerator(useInheritedGenerator ? beanNameGenerator : (BeanNameGenerator)BeanUtils.instantiateClass(generatorClass)); ScopedProxyMode scopedProxyMode = (ScopedProxyMode)componentScan.getEnum("scopedProxy"); if(scopedProxyMode != ScopedProxyMode.DEFAULT) { scanner.setScopedProxyMode(scopedProxyMode); } else { Class resolverClass = componentScan.getClass("scopeResolver"); scanner.setScopeMetadataResolver((ScopeMetadataResolver)BeanUtils.instantiateClass(resolverClass)); } //包含注解类 AnnotationAttributes aannotationattributes[] = componentScan.getAnnotationArray("includeFilters"); int i = aannotationattributes.length; for(int j = 0; j < i; j++) { AnnotationAttributes filter = aannotationattributes[j]; TypeFilter typeFilter; for(Iterator iterator = typeFiltersFor(filter).iterator(); iterator.hasNext(); scanner.addIncludeFilter(typeFilter)) typeFilter = (TypeFilter)iterator.next(); } //剔除注解类 aannotationattributes = componentScan.getAnnotationArray("excludeFilters"); i = aannotationattributes.length; for(int k = 0; k < i; k++) { AnnotationAttributes filter = aannotationattributes[k]; TypeFilter typeFilter; for(Iterator iterator1 = typeFiltersFor(filter).iterator(); iterator1.hasNext(); scanner.addExcludeFilter(typeFilter)) typeFilter = (TypeFilter)iterator1.next(); } List basePackages = new ArrayList(); Object aobj[] = componentScan.getStringArray("value"); int l = aobj.length; for(int i1 = 0; i1 < l; i1++) { String pkg = aobj[i1]; if(StringUtils.hasText(pkg)) basePackages.add(pkg); } aobj = componentScan.getStringArray("basePackages"); l = aobj.length; for(int j1 = 0; j1 < l; j1++) { String pkg = aobj[j1]; if(StringUtils.hasText(pkg)) basePackages.add(pkg); } aobj = componentScan.getClassArray("basePackageClasses"); l = aobj.length; for(int k1 = 0; k1 < l; k1++) { Class clazz = aobj[k1]; basePackages.add(ClassUtils.getPackageName(clazz)); } //扫描基本包 return scanner.doScan(StringUtils.toStringArray(basePackages)); } }
//ClassPathBeanDefinitionScanner,bean定义扫描
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider { protected transient Set doScan(String basePackages[]) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set beanDefinitions = new LinkedHashSet(); String as[] = basePackages; int i = as.length; label0: for(int j = 0; j < i; j++) { String basePackage = as[j]; Set candidates = findCandidateComponents(basePackage); Iterator iterator = candidates.iterator(); do { if(!iterator.hasNext()) continue label0; BeanDefinition candidate = (BeanDefinition)iterator.next(); ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(candidate); //设置bean作用域 candidate.setScope(scopeMetadata.getScopeName()); String beanName = beanNameGenerator.generateBeanName(candidate, registry); if(candidate instanceof AbstractBeanDefinition) //bean自动注入auotwired处理 postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName); if(candidate instanceof AnnotatedBeanDefinition) //处理lazy等注解 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate); if(checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, registry); beanDefinitions.add(definitionHolder); registerBeanDefinition(definitionHolder, registry); } } while(true); } return beanDefinitions; } //bean自动注入@auotwired处理 protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) { beanDefinition.applyDefaults(beanDefinitionDefaults); if(autowireCandidatePatterns != null) beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(autowireCandidatePatterns, beanName)); } }
//Servlet上下文监听器
public interface ServletContextListener extends EventListener { public abstract void contextInitialized(ServletContextEvent servletcontextevent); public abstract void contextDestroyed(ServletContextEvent servletcontextevent); }
//上下文配置文件资源
public class ClassPathResource extends AbstractFileResolvingResource { //构遭上下文配置文件资源 public ClassPathResource(String path, ClassLoader classLoader) { Assert.notNull(path, "Path must not be null"); String pathToUse = StringUtils.cleanPath(path); if(pathToUse.startsWith("/")) pathToUse = pathToUse.substring(1); this.path = pathToUse; this.classLoader = classLoader == null ? ClassUtils.getDefaultClassLoader() : classLoader; } //解决上下文配置文件URL protected URL resolveURL() { if(clazz != null) return clazz.getResource(path); if(classLoader != null) return classLoader.getResource(path); else return ClassLoader.getSystemResource(path); } //获取上下文配置文件输入流 public InputStream getInputStream() throws IOException { InputStream is; if(clazz != null) is = clazz.getResourceAsStream(path); else if(classLoader != null) is = classLoader.getResourceAsStream(path); else is = ClassLoader.getSystemResourceAsStream(path); if(is == null) throw new FileNotFoundException((new StringBuilder()).append(getDescription()).append(" cannot be opened because it does not exist").toString()); else return is; } //获取上下文配置文件URL public URL getURL() throws IOException { URL url = resolveURL(); if(url == null) throw new FileNotFoundException((new StringBuilder()).append(getDescription()).append(" cannot be resolved to URL because it does not exist").toString()); else return url; } //创建相对路径上下文配置文件资源 public Resource createRelative(String relativePath) { String pathToUse = StringUtils.applyRelativePath(path, relativePath); return new ClassPathResource(pathToUse, classLoader, clazz); } //获取配置文件名 public String getFilename() { return StringUtils.getFilename(path); } private final String path;//路径 private ClassLoader classLoader;//上下文加载类 private Class clazz; }
//属性配置文件加载工具
public abstract class PropertiesLoaderUtils { //加载配置文件 public static Properties loadProperties(Resource resource) throws IOException { Properties props = new Properties(); fillProperties(props, resource); return props; } //填充配置属性 public static void fillProperties(Properties props, Resource resource) throws IOException { InputStream is = resource.getInputStream(); String filename = resource.getFilename(); if(filename != null && filename.endsWith(".xml")) props.loadFromXML(is); else props.load(is); is.close(); is.close(); } private static final String XML_FILE_EXTENSION = ".xml"; }
//Properties
public class Properties extends Hashtable { //从XML文件输入流加载配置文件 public synchronized void loadFromXML(InputStream inputstream) throws IOException, InvalidPropertiesFormatException { if(inputstream == null) { throw new NullPointerException(); } else { XMLUtils.load(this, inputstream); inputstream.close(); return; } } }
//ServletContextEvent
public class ServletContextEvent extends EventObject { public ServletContextEvent(ServletContext source) { super(source); } public ServletContext getServletContext() { return (ServletContext)super.getSource(); } }
//ApplicationContext
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver { public abstract String getId(); public abstract String getApplicationName(); public abstract String getDisplayName(); public abstract long getStartupDate(); public abstract ApplicationContext getParent(); public abstract AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException; }
//WebApplicationContext
public interface WebApplicationContext extends ApplicationContext { public abstract ServletContext getServletContext(); public static final String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = (new StringBuilder()).append(org/springframework/web/context/WebApplicationContext.getName()).append(".ROOT").toString(); public static final String SCOPE_REQUEST = "request"; public static final String SCOPE_SESSION = "session"; public static final String SCOPE_GLOBAL_SESSION = "globalSession"; public static final String SCOPE_APPLICATION = "application"; public static final String SERVLET_CONTEXT_BEAN_NAME = "servletContext"; public static final String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters"; public static final String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes"; }
//ConfigurableWebApplicationContext
public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext { public abstract void setServletContext(ServletContext servletcontext); public abstract void setServletConfig(ServletConfig servletconfig); public abstract ServletConfig getServletConfig(); public abstract void setNamespace(String s); public abstract String getNamespace(); public abstract void setConfigLocation(String s); public abstract void setConfigLocations(String as[]); public abstract String[] getConfigLocations(); public static final String APPLICATION_CONTEXT_ID_PREFIX = (new StringBuilder()).append(org/springframework/web/context/WebApplicationContext.getName()).append(":").toString(); public static final String SERVLET_CONFIG_BEAN_NAME = "servletConfig"; }
//StandardServletEnvironment
public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment { public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig) { //初始化ServletPropertySources WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig); } public static final String SERVLET_CONTEXT_PROPERTY_SOURCE_NAME = "servletContextInitParams"; public static final String SERVLET_CONFIG_PROPERTY_SOURCE_NAME = "servletConfigInitParams"; public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiProperties"; }
//WebApplicationContext工具类
public abstract class WebApplicationContextUtils { //初始化servletContextInitParams public static void initServletPropertySources(MutablePropertySources propertySources, ServletContext servletContext, ServletConfig servletConfig) { Assert.notNull(propertySources, "propertySources must not be null"); if(servletContext != null && propertySources.contains("servletContextInitParams") && (propertySources.get("servletContextInitParams") instanceof org.springframework.core.env.PropertySource.StubPropertySource)) propertySources.replace("servletContextInitParams", new ServletContextPropertySource("servletContextInitParams", servletContext)); if(servletConfig != null && propertySources.contains("servletConfigInitParams") && (propertySources.get("servletConfigInitParams") instanceof org.springframework.core.env.PropertySource.StubPropertySource)) propertySources.replace("servletConfigInitParams", new ServletConfigPropertySource("servletConfigInitParams", servletConfig)); } }
//ApplicationContextInitializer
public interface ApplicationContextInitializer { public abstract void initialize(ConfigurableApplicationContext configurableapplicationcontext); }
//bean工具类
public abstract class BeanUtils { //初始化Class public static Object instantiateClass(Class clazz) throws BeanInstantiationException { Assert.notNull(clazz, "Class must not be null"); if(clazz.isInterface()) throw new BeanInstantiationException(clazz, "Specified class is an interface"); return instantiateClass(clazz.getDeclaredConstructor(new Class[0]), new Object[0]); NoSuchMethodException ex; ex; throw new BeanInstantiationException(clazz, "No default constructor found", ex); } //根据构造函数初始化Object public static transient Object instantiateClass(Constructor ctor, Object args[]) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null"); ReflectionUtils.makeAccessible(ctor); return ctor.newInstance(args); InstantiationException ex; ex; throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is it an abstract class?", ex); ex; throw new BeanInstantiationException(ctor.getDeclaringClass(), "Is the constructor accessible?", ex); ex; throw new BeanInstantiationException(ctor.getDeclaringClass(), "Illegal arguments for constructor", ex); ex; throw new BeanInstantiationException(ctor.getDeclaringClass(), "Constructor threw exception", ex.getTargetException()); } }
总结:
Spring上下文加载监听,在静态语句块中加载配置文件contextConfigLocation,
然后初始化ServletContext,以便spring容器可以直接访问web容器上下文,注册bean后置处理器,构造bean,初始化消息源,监听器;在构造bean的过程中通过ConfigurationClassParser来解析bean,处理注解,IOC等。
评论
3 楼
Donald_Draper
2017-06-06
andypeker 写道
andypeker 写道
请教一下,initWebApplicationContext方法里的loadParentContext加载的父上下文,指的是哪个上下文?是否是servletContext呢?按理说,wac是根上下文了,除了servletContext没有其他可能。
如果有哪位大哥知道,请务必不吝赐教!
这是很早写的一篇文章,都忘的差不多了,加载父类代码为
protected ApplicationContext loadParentContext(ServletContext servletContext) { ApplicationContext parentContext = null; //取得Web.xml初始化参数配置中对LOCATOR_FACTORY_SELECTOR_PARAM的配置串,这是Bean工厂定位器使用的Bean工厂的路径,如果这个值没有配置,则使用缺省的classpath*:beanRefFactory.xml String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM); //取得Web.xml初始化参数配置中对LOCATOR_FACTORY_KEY_PARAM的配置串,这是用来取得Bean工厂的关键字 String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM); if (parentContextKey != null) { //locatorFactorySelector如果为空,则使用缺省值classpath*:beanRefFactory.xml初始化Bean工厂定位器 BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); Log logger = LogFactory.getLog(ContextLoader.class); if (logger.isDebugEnabled()) { logger.debug("Getting parent context definition: using parent context key of '" + parentContextKey + "' with BeanFactoryLocator"); } //Bean工厂定位器从配置的Bean工厂中找到制定关键字(参数LOCATOR_FACTORY_KEY_PARAM的值) 的工厂 this.parentContextRef = locator.useBeanFactory(parentContextKey); //进而取得一个应用程序环境,这个应用程序环境作为根共享应用程序环境的父环境 parentContext = (ApplicationContext) this.parentContextRef.getFactory(); } return parentContext; }
Spring Web MVC是依赖于Spring环境的定义的,而每一个Spring环境可以最多有一个父环境的引用。
http://blog.csdn.net/robertleepeak/article/details/5891750
2 楼
andypeker
2017-06-04
andypeker 写道
请教一下,initWebApplicationContext方法里的loadParentContext加载的父上下文,指的是哪个上下文?是否是servletContext呢?按理说,wac是根上下文了,除了servletContext没有其他可能。
如果有哪位大哥知道,请务必不吝赐教!
1 楼
andypeker
2017-06-04
请教一下,initWebApplicationContext方法里的loadParentContext加载的父上下文,指的是哪个上下文?是否是servletContext呢?按理说,wac是根上下文了,除了servletContext没有其他可能。
发表评论
-
Spring的RequestMappingHandlerMapping详解
2016-09-23 08:40 4596深刻理解IdentityHashMap:http://dona ... -
Spring-RequestMappingHandlerAdapter初始化及请求处理
2016-09-22 11:50 10574看这篇文章之前,最好先看下面这篇,以便更好的理解handler ... -
Spring+Mybatis多数据源的实现
2016-09-21 18:15 3094浅谈Spring事务隔离级别:http://www.cnblo ... -
Spring的DefaultAnnotationHandlerMapping详解
2016-09-20 08:47 5841前面我们讲解过Dispatcher ... -
Spring-DispatcherServlet请求处理
2016-09-19 15:42 1687Spring-DispatcherServlet初始化详解:h ... -
Spring-DispatcherServlet初始化详解
2016-09-19 15:03 3692Spring-DispatcherServlet请求处理:ht ... -
JobDetailFactoryBean与MethodInvokingJobDetailFactoryBean源码分析
2016-09-13 16:07 4304Spring与Quartz集成详解:http://donald ... -
Spring与Quartz集成-源码分析
2016-09-13 11:50 2716在阅读以下文章之前,如果对Quartz任务调度不是很熟悉,请看 ... -
Spring与Quartz集成详解
2016-09-09 17:52 2818首先这个所有的依赖包就不需要多讲了,首先下载Quazrt发布包 ... -
Spring,ApplicationContextAware的作用
2016-08-24 17:38 7引用:http://blog.csdn.net/kaiwii/ ... -
Spring Interceptor
2016-05-31 17:12 571Spring Interceptor相关知识:http://h ... -
基于注解的Spring AOP
2016-05-31 16:05 921Spring AOP 基本概念:http://hotstron ... -
Spring的Task定时器
2016-05-31 10:34 7061.开启注解,定义扫描包 <mvc:annotation ...
相关推荐
在`web.xml`中添加`ContextLoaderListener`监听器,以初始化Spring应用上下文: ```xml <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> ``` 3. **指定Spring...
在Java Web开发中,`org.springframework.web.context.ContextLoaderListener` 是Spring框架的一部分,它负责初始化一个Web应用程序的Spring上下文。这个监听器是基于Servlet容器(如Tomcat、Jetty等)的,当Web应用...
这个错误通常出现在尝试启动基于Spring MVC的Web应用程序时,因为它无法找到用于初始化Spring应用上下文的监听器。 `ContextLoaderListener`是Spring框架的一部分,它负责在Web应用启动时加载并管理Spring的应用上...
`ContextLoaderListener`是一个实现了`javax.servlet.ServletContextListener`接口的类,它的主要职责是在Web应用启动时初始化Spring应用上下文,并在应用关闭时清理资源。这个过程涉及以下几个关键知识点: 1. **...
`ContextLoaderListener`是Spring框架中的一个监听器,它负责初始化Spring应用上下文。下面将详细解析`web.xml`中`ContextLoaderListener`的运行过程。 ### 1. `web.xml`的作用 `web.xml`文件主要用来定义Servlet、...
2. **配置Spring监听器**:在`web.xml`文件中,需要配置一个Spring的上下文监听器`ContextLoaderListener`,该监听器负责初始化Spring的ApplicationContext。具体配置如下所示: ```xml <listener-class>org....
-- 设置Spring上下文配置文件的位置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/QuartzConfig.xml</param-value> </context-param> <!-- 加载Spring的...
下面我们使用ContextLoaderListener作为载入器作一个详细的分析,这个Servlet的监听器是根上下文被载入的地方,也是整个 Spring web应用加载上下文的第一个地方;从加载过程我们可以看到,首先从Servlet事件中得到...
Tool模块则是一组辅助工具,如ContextLoaderListener和ContextLoaderServlet,用于启动和加载Spring应用上下文。4.1.1.RELEASE版本在初始化速度和资源利用效率上有所提升。 10. **JEE(Java Enterprise Edition)*...
在Spring项目中,监听器(Listener)扮演着关键的角色,特别是在Web应用程序的上下文管理方面。本文将深入探讨Spring框架中的监听器,特别是`ContextLoaderListener`的作用及其配置。 `ContextLoaderListener`是...
- 创建`web.xml`作为Web应用的部署描述符,配置Spring的前端控制器DispatcherServlet以及Servlet上下文监听器ContextLoaderListener,它们负责初始化Spring应用上下文。 - 编写`dispatcher-servlet.xml`,这是...
ContextLoaderListener则是Spring容器的启动监听器,它负责初始化Spring应用上下文(ApplicationContext)。当Web应用启动时,ContextLoaderListener会读取Web-INF下的applicationContext.xml配置文件,创建并加载...
- 配置Web.xml文件,设置DispatcherServlet的初始化参数和监听器,以便加载Spring上下文。 - 编写Controller,处理HTTP请求,并调用Service完成业务逻辑。 5. **项目源码分析**:在压缩包中的项目源码,我们可以...
- **配置 web.xml**:在`web.xml`中配置Spring上下文初始化监听器,以便于启动时加载Spring配置。 3. **整合 Spring 和 Struts2** - **加入 Spring 插件**:在Struts2中集成Spring插件,以实现Action的注入。 - ...
- 配置 Spring 的上下文监听器,以便在应用启动时加载 Spring 配置文件。 ```xml <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> <context-param> <param-name...
- `ContextLoaderListener`是一个监听器类,负责初始化Spring应用上下文。它会在Web应用启动时读取`web.xml`中的配置,并加载相应的bean定义。 4. **DispatcherServlet配置**: - `DispatcherServlet`是Spring ...
- **配置Spring上下文**:定义Spring的配置文件位置,并启用Spring的上下文加载监听器。 ```xml <!-- Spring上下文配置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB...
- 在 `web.xml` 中添加 `ContextLoaderListener` 监听器,以便启动时加载 Spring 上下文。 - `contextConfigLocation` 参数指定 Spring 配置文件的位置,例如 `classpath:applicationContext.xml`。 4. **Spring ...