Spring中ApplicationContext加载机制

合集下载

contextrefreshedevent event -回复

contextrefreshedevent event -回复

contextrefreshedevent event -回复什么是ContextRefreshedEvent(Spring的ContextRefreshedEvent 事件)?在Spring框架中,ContextRefreshedEvent是一个事件类,它表示ApplicationContext(应用程序上下文)已被初始化或刷新完成。

当ApplicationContext被启动并且所有的Bean都已经装配完成时,该事件将被触发。

这一事件是在整个Spring应用程序初始化的过程中非常重要的一个步骤。

为什么ContextRefreshedEvent事件很重要?对于大多数Spring应用程序而言,ContextRefreshedEvent事件被认为是一个重要的里程碑。

这是因为在这个阶段,Spring应用程序已经完成了所有的初始化工作,并且所有的Bean都已经被创建。

此外,它也代表着应用程序可以开始处理请求了。

ContextRefreshedEvent的触发时机是什么?当Spring应用程序启动时,它会初始化ApplicationContext并加载所有配置文件。

在加载完所有的Bean定义之后,Spring会触发ContextRefreshedEvent事件。

这个事件在Spring初始化的过程中只会触发一次。

ContextRefreshedEvent的触发顺序是怎样的?ContextRefreshedEvent事件的触发顺序是根据应用程序的Bean加载顺序来确定的。

Spring将按照配置文件中定义的顺序加载Bean,并按照这个顺序触发ContextRefreshedEvent事件。

ContextRefreshedEvent事件的处理方式是什么?在Spring应用程序中,我们可以通过实现ApplicationListener接口来监听并处理ContextRefreshedEvent事件。

当ContextRefreshedEvent被触发时,我们可以编写相关的代码来处理这个事件。

基于spring-mvc.xml和application-context.xml的配置与深入理解

基于spring-mvc.xml和application-context.xml的配置与深入理解

基于spring-mvc.xml和application-context.xml的配置与深⼊理解⽬录前沿1、application-context.xml是全局的2、spring-mvc.xml 是spring mvc的配置(1)application-context.xml配置1、⾸先介绍⼀下启动⼀个项⽬的整体流程:2、现在开始正式讲解applicationContext.xml中的配置内容⾸先准备db.properties 配置⽂件SqlSessionTemplate介绍:applicationContext.xml配置:Spring和Mybatis整合有两种⽅式事务管理的两种⽅式:(2)sping-mvc.xml的配置1.⾃动扫描2.注解驱动3.静态资源处理4.避免IE执⾏AJAX时,返回JSON出现下载⽂件5.启动SpringMVC的注解功能,完成请求和注解POJO的映射6.配置⽂件上传7.配置viewResolver视图解析8.定义跳转的⽂件的前后缀,视图模式配置前沿1、application-context.xml是全局的应⽤于多个serverlet,配合listener⼀起使⽤,web.xml中配置如下:<!-- 配置监听器 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param>2、spring-mvc.xml 是spring mvc的配置web.xml中配置如下:<!--配置springmvc DispatcherServlet--><servlet><servlet-name>springMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:config/spring-mvc.xml</param-value></init-param><load-on-startup>1</load-on-startup><async-supported>true</async-supported></servlet>application-context.xml这个⼀般是采⽤⾮spring mvc架构,⽤来加载Application Context。

获取SpringApplicationContext容器上下文对象实例

获取SpringApplicationContext容器上下文对象实例

获取SpringApplicationContext容器上下⽂对象实例Spring ApplicationContext 容器可以加载配置⽂件中定义的 bean,将所有的 bean 集中在⼀起,当有请求的时候分配 bean。

如果说BeanFactory是Spring的⼼脏,那么ApplicationContext就是完整的⾝躯了。

ApplicationContext由BeanFactory派⽣⽽来,提供了更多⾯向实际应⽤的功能。

另外,它增加了企业所需要的功能,⽐如,从属性⽂件中解析⽂本信息和将事件传递给所指定的监听器。

这个容器在 org.springframework.context.ApplicationContext interface 接⼝中定义。

ApplicationContext的初始化和BeanFactory有⼀个重⼤的区别:BeanFactory在初始化容器时,并未实例化Bean,直到第⼀次访问某个Bean时才实例⽬标Bean;⽽ApplicationContext则在初始化应⽤上下⽂时就实例化所有单实例的Bean。

因此ApplicationContext的初始化时间会⽐BeanFactory稍长⼀些,不过稍后的调⽤则没有这样的缺陷了。

传统的获取ApplicationContext的⽅式有很多种,下⾯⼩编简单地介绍⼏种常⽤的⽅式!在获取ApplicationContext实例后,就可以调⽤getBean(beanName)返回Bean 了。

为了验证,假设已经构建了Spring Boot项⽬,在包com.eg.wiener.config中新增测试类。

package com.eg.wiener.config;import org.springframework.context.annotation.Bean;import org.springframework.stereotype.Service;@Servicepublic class BeanTest {@Beanpublic BeanTest getBeanObj() {BeanTest bean = new BeanTest();System.out.println("调⽤⽅法:" + bean);return bean;}}直接注⼊@Autowiredprivate ApplicationContext ctx;@GetMapping("/getContext")public String getContext(){Object bean1 = ctx.getBean("getBeanObj");return String.format(" ctx 打印bean %s", bean1);}启动项⽬,可以找到⽇志:2020-06-27 10:50:16.879 INFO 12272 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 2187 ms 调⽤⽅法:com.eg.wiener.config.BeanTest@3c74aa0d说明bean已经被注⼊Spring容器,默认bean的名称就是其⽅法名。

SpringBoot中获取ApplicationContext的三种方式

SpringBoot中获取ApplicationContext的三种方式

SpringBoot中获取ApplicationContext的三种⽅式pringBoot中获取ApplicationContext的三种⽅式ApplicationContext是什么?简单来说就是Spring中的容器,可以⽤来获取容器中的各种bean组件,注册监听事件,加载资源⽂件等功能。

Application Context获取的⼏种⽅式1 直接使⽤Autowired注⼊@Componentpublic class Book1 {@Autowiredprivate ApplicationContext applicationContext;public void show (){System.out.println(applicationContext.getClass());}}2 利⽤ spring4.3 的新特性使⽤spring4.3新特性但是存在⼀定的局限性,必须满⾜以下两点:1 构造函数只能有⼀个,如果有多个,就必须有⼀个⽆参数的构造函数,此时,spring会调⽤⽆参的构造函数2 构造函数的参数,必须在spring容器中存在@Componentpublic class Book2 {private ApplicationContext applicationContext;public Book2(ApplicationContext applicationContext){System.out.println(applicationContext.getClass());this.applicationContext=applicationContext;}public void show (){System.out.println(applicationContext.getClass());}}3 实现spring提供的接⼝ ApplicationContextAwarespring 在bean 初始化后会判断是不是ApplicationContextAware的⼦类,调⽤setApplicationContext()⽅法,会将容器中ApplicationContext传⼊进去@Componentpublic class Book3 implements ApplicationContextAware {private ApplicationContext applicationContext;public void show (){System.out.println(applicationContext.getClass());}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}}结果获取三次:。

HttpSessionListener、ServletContextListener

HttpSessionListener、ServletContextListener

关于Listener详解ServletContextListenerServletContextListener接口能够监听ServletContext对象的生命周期,实际上就是监听Web应用的生命周期。

当Servlet容器启动或终止Web应用时,会触发ServletContextEvent事件,该事件由ServletContextListener来处理。

在ServletContextListener接口中定义了处理ServletContextEvent事件的两个方法:contextInitialized (ServletContextEvent event)当Servlet容器启动Web应用时调用该方法。

在调用完该方法之后,容器再对Filter初始化,并且对那些在Web应用启动时就需要被初始化的Servlet进行初始化。

用途:Web服务器启动时加载数据到内存中………….. contextDestroyed(ServletContextEvent event)当Servlet容器终止Web应用时调用该方法。

在调用该方法之前,容器会先销毁所有的Servlet和Filter过滤器。

public ServletContext getServletContext();//ServletContextEvent事件:取得一个ServletContext(application)对象HttpSessionListenerSession创建事件发生在每次一个新的session创建的时候,类似地Session失效事件发生在每次一个Session失效的时候。

对Session的整体状态的监听。

对每一个正在访问的用户,J2EE应用服务器会为其建立一个对应的HttpSession 对象。

当一个浏览器第一次访问网站的时候,J2EE应用服务器会新建一个HttpSession对象,并触发HttpSession创建事件,如果注册了HttpSessionListener事件监听器,则会调用HttpSessionListener事件监听器的sessionCreated方法。

Spring中加载xml配置文件的几种方式

Spring中加载xml配置文件的几种方式

项目中一个需求就是所有的功能都是插件的形式装入系统,这就需要利用Spring去动态加载某一位置下的配置文件,就总结了下Spring中加载xml配置文件的方式, xml是最常见的spring 应用系统配置源。

Spring中的几种容器都支持使用xml装配bean,包括:XmlBeanFactory,ClassPathXmlApplicationContext,FileSystemXmlApplicationContext,XmlWebApplicationContext,.....一: XmlBeanFactory 引用资源1.Resource cr = new ClassPathResource("applicationContext.xml");BeanFactory bf=new XmlBeanFactory(cr);UserDao userDao = (UserDao)bf.getBean("userDao");二: ClassPathXmlApplicationContext 编译路径使用ClassPathXmlApplicationContext对象获取,必须把applicationContext.xml放置到类的加载路径中,也就是Src下面1.ApplicationContext factory=new ClassPathXmlApplicationContext("classpath:appcontext.xml");// src目录下的2.ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao)context.getBean("userDao");3.ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext-oracle.xml","applicationContext.xml"});UserDao userDao = (UserDao)context.getBean("userDao");// src/conf 目录下的4.ApplicationContext factory=new ClassPathXmlApplicationContext("conf/appcontext.xml");5.ApplicationContext factory=new ClassPathXmlApplicationContext("file:G:/Test/src/appcontext.xml");三: FileSystemXmlApplicationContext用文件系统的路径必须把applicationContext.xml放置到工程目录下面,也就是项目路径的下面1.ApplicationContext factory=newFileSystemXmlApplicationContext("src/appcontext.xml");//使用了classpath: 前缀,作为标志, 这样,FileSystemXmlApplicationContext 也能够读入classpath下的相对路径没有classpath的话就是从当前的工作目录2.ApplicationContext factory=newFileSystemXmlApplicationContext("classpath:appcontext.xml");3.ApplicationContext factory=newFileSystemXmlApplicationContext("file:G:/Test/src/appcontext.xml");4.ApplicationContext factory=newFileSystemXmlApplicationContext("G:/Test/src/appcontext.xml");四: XmlWebApplicationContext是专为Web工程定制的。

Springboot:解决FailedtoloadApplicationContext问题

Springboot:解决FailedtoloadApplicationContext问题

Springboot:解决FailedtoloadApplicationContext问题最近在做spring junit 做单元测试中,报 Failed to load ApplicationContext 错误。

import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)@SpringBootTestpublic class DemoApplicationTests {@Autowiredprivate Person person;@Testpublic void contextLoads(){System.out.println(person);}}unit和test也都配置了相关依赖<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>但还是报 Failed to load ApplicationContext 错误ng.IllegalStateException: Failed to load ApplicationContextat org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)at org.junit.runners.ParentRunner.run(ParentRunner.java:363)at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceCon at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:655)at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:635)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)at mbda$doGetBean$0(AbstractBeanFactory.java:323)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:893)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)... 24 moreCaused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springfram at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:650)... 43 moreCaused by: org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver classat org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.determineDriverClassName(DataSourceProperties.java:234)at org.springframework.boot.autoconfigure.jdbc.DataSourceProperties.initializeDataSourceBuilder(DataSourceProperties.java:175)at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration.createDataSource(DataSourceConfiguration.java:43)at org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari.dataSource(DataSourceConfiguration.java:85)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at ng.reflect.Method.invoke(Method.java:497)at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)... 44 more⼀直找不到原因,卡壳了⽼半天,在⽹上也找了好多资料,也没有效果。

spring原理机制

spring原理机制

spring原理机制转⾃:/nrain2/article/details/454593111,关于spring容器:spring容器是Spring的核⼼,该容器负责管理spring中的java组件,ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");//这种⽅式实例化容器,容器会⾃动预初始化所有Bean实例ctx.getBean("beanName");ApplicationContext 实例正是Spring容器。

ApplicationContext容器默认会实例化所有的singleton BeanSpring容器并不强制要求被管理组件是标准的javabean。

2,Spring的核⼼机制:依赖注⼊。

不管是依赖注⼊(Dependency Injection)还是控制反转(Inversion of Conctrol),其含义完全相同:当某个java实例(调⽤者)需要调⽤另⼀个java实例(被调⽤者)时,传统情况下,通过调⽤者来创建被调⽤者的实例,通常通过new来创建,⽽在依赖注⼊的模式下创建被调⽤者的⼯作不再由调⽤者来完成,因此称之为"控制反转";创建被调⽤者实例的⼯作通常由Spring来完成,然后注⼊调⽤者,所以也称之为"依赖注⼊"。

3,依赖注⼊⼀般有2中⽅式:设置注⼊:IoC容器使⽤属性的setter⽅式注⼊被依赖的实例。

<property name="" ref="">构造注⼊:IoC容器使⽤构造器来注⼊被依赖的实例。

<constructor-arg ref="">配置构造注⼊的时候<constructor-arg>可以配置index属性,⽤于指定该构造参数值作为第⼏个构造参数值。

spring中通过ApplicationContextgetBean获取注入对象的方法实例

spring中通过ApplicationContextgetBean获取注入对象的方法实例

spring中通过ApplicationContextgetBean获取注⼊对象的⽅法实例⽤SpringContextUtil实现ApplicationContextAwarepackage util;import java.util.Locale;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class SpringContextUtilimplements ApplicationContextAware{private static ApplicationContext context;@Overridepublic void setApplicationContext(ApplicationContext contex)throws BeansException{System.out.println("--------------------contex---------"+contex);SpringContextUtil.context = contex;}public static ApplicationContext getApplicationContext() {return context;}public static Object getBean(String beanName) {return context.getBean(beanName);}public static String getMessage(String key) {return context.getMessage(key, null, Locale.getDefault());}}⼯具类package redis;import redis.clients.jedis.JedisPool;import util.SpringContextUtil;public class RedisUtil {private static JedisPool jedisPool;static{jedisPool = (JedisPool)SpringContextUtil.getBean("jedisPool");}public static JedisPool getJedisPool(){if(jedisPool == null){jedisPool = (JedisPool)SpringContextUtil.getBean("jedisPool");}return jedisPool;}public void flusDB(){jedisPool.getResource().flushDB();}public static String set(String key,String value){return jedisPool.getResource().set(key, value);}public static String get(String key){return jedisPool.getResource().get(key);}public static Long del(String key){return jedisPool.getResource().del(key);}}在Spring的配置⽂件中配置这个类,Spring容器会在加载完Spring容器后把上下⽂对象调⽤这个对象中的setApplicationContext⽅法<!--1 ⾃动扫描将标注Spring注解的类⾃动转化Bean--><context:component-scan base-package="com.first,com.util" /><!--2 加载数据资源属性⽂件 --><bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><value>classpath:jdbc.properties</value><value>classpath:redis.properties</value></list></property></bean><bean id="springContextUtil" class="util.SpringContextUtil"></bean><import resource="redis-config.xml"/>在web项⽬中的web.xml中配置加载Spring容器的Listener<!-- 初始化Spring容器,让Spring容器随Web应⽤的启动⽽⾃动启动 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>spring配置⽂件注⼊Bean类<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"><property name="maxIdle" value="300" /> <!-- 最⼤能够保持idel状态的对象数 --><property name="testOnBorrow" value="true" /> <!-- 当调⽤borrow Object⽅法时,是否进⾏有效性检查 --><property name="maxActive" value="200" /><property name="minIdle" value="10"/><property name="maxWait" value="300" /><property name="testOnReturn" value="true" /><property name="testWhileIdle" value="true" /></bean><bean id="jedisPool" class="redis.clients.jedis.JedisPool"><constructor-arg name="poolConfig" ref="jedisPoolConfig" /><constructor-arg name="host" value="${redis_addr}" /><constructor-arg name="port" value="${redis_port}" type="int" /><constructor-arg name="timeout" value="${redis_timeout}" type="int" /><constructor-arg name="password" value="#{'${redis_password}'!=''?'${redis_password}':null}" /><constructor-arg name="database" value="${redis_db_index}" type="int" /></bean>总结以上就是这篇⽂章的全部内容了,希望本⽂的内容对⼤家的学习或者⼯作具有⼀定的参考学习价值,谢谢⼤家对的⽀持。

contextrefreshedevent event -回复

contextrefreshedevent event -回复

contextrefreshedevent event -回复ContextRefreshedEvent是Spring Framework中的一个事件,它在ApplicationContext初始化或刷新时发布。

在本文中,我们将详细讨论ContextRefreshedEvent的背景、原理、使用场景以及如何监听和处理该事件。

一、ContextRefreshedEvent的背景和原理在深入研究ContextRefreshedEvent之前,我们先来了解一下Spring Framework和事件驱动编程的概念。

Spring Framework是一个开源的Java应用程序开发框架,它提供了高效、可扩展和易于维护的基础设施,用于创建企业级应用程序。

Spring的核心原则是依赖注入和面向切面编程,它帮助我们通过IOC(Inverse of Control)容器管理对象之间的依赖关系并提供了强大的AOP(Aspect Oriented Programming)支持。

事件驱动编程是一种编程范式,它基于事件和事件处理器之间的交互来驱动程序的执行。

在这种模型中,事件是系统中发生的某个特定动作或状态的表示,而事件处理器则负责处理和响应这些事件。

在Spring Framework中,事件驱动编程是通过ApplicationEvent和EventListener接口的实现来实现的。

ApplicationEvent是所有Spring 事件的基类,而EventListener是用于处理这些事件的接口。

ContextRefreshedEvent是Spring Framework中的一个具体实现类,它表示ApplicationContext的初始化或刷新完成的事件。

当ApplicationContext初始化完毕后,Spring会发布ContextRefreshedEvent事件,以通知所有对该事件感兴趣的监听器。

二、ContextRefreshedEvent的使用场景ContextRefreshedEvent是Spring Framework中非常重要的一个事件,它在很多场景下都被广泛使用。

Spring初始化ApplicationContext为null

Spring初始化ApplicationContext为null

Spring初始化ApplicationContext为null1. ApplicationContextAware初始化通过它Spring容器会⾃动把上下⽂环境对象调⽤ApplicationContextAware接⼝中的setApplicationContext⽅法。

我们在ApplicationContextAware的实现类中,就可以通过这个上下⽂环境对象得到Spring容器中的Bean。

使⽤⽅法如下:1.实现ApplicationContextAware接⼝:package com.bis.majian.practice.module.spring.util;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class SpringContextHelper implements ApplicationContextAware {private static ApplicationContext context = null;@Overridepublic void setApplicationContext(ApplicationContext applicationContext)throws BeansException {context = applicationContext;}public static Object getBean(String name){return context.getBean(name);}} 2.在Spring的配置⽂件中配置这个类,Spring容器会在加载完Spring容器后把上下⽂对象调⽤这个对象中的setApplicationContext⽅法:<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance" xmlns:tx="/schema/tx"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-3.0.xsd/schema/tx/schema/tx/spring-tx-3.0.xsd/schema/context/schema/context/spring-context-3.0.xsd" default-autowire="byName"><bean id="springContextHelper" class="com.bis.majian.practice.module.spring.util.SpringContextHelper"></bean><context:component-scan base-package="com.bis.majian.practice.module.*" /></beans> 3.在web项⽬中的web.xml中配置加载Spring容器的Listener:<!-- 初始化Spring容器,让Spring容器随Web应⽤的启动⽽⾃动启动 --><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>4.在项⽬中即可通过这个SpringContextHelper调⽤getBean()⽅法得到Spring容器中的对象了。

spring成神之路第三篇:Spring容器基本使用及原理(ApplicationCont。。。

spring成神之路第三篇:Spring容器基本使用及原理(ApplicationCont。。。

spring成神之路第三篇:Spring容器基本使⽤及原理(ApplicationCont。

1. jdk1.82. idea3. maven-3.6.14. spring-5.2.3.RELEASEIOC容器是具有依赖注⼊功能的容器,负责对象的实例化、对象的初始化,对象和对象之间依赖关系配置、对象的销毁、对外提供对象的查找等操作,对象的整个⽣命周期都是由容器来控制。

我们需要使⽤的对象都由ioc容器进⾏管理,不需要我们再去⼿动通过new的⽅式去创建对象,由ioc 容器直接帮我们组装好,当我们需要使⽤的时候直接从ioc容器中直接获取就可以了。

那么spring ioc容器是如何知道需要管理哪些对象呢?需要我们给ioc容器提供⼀个配置清单,这个配置⽀持xml格式和java注解的⽅式,在配置⽂件中列出需要让ioc容器管理的对象,以及可以指定让ioc容器如何构建这些对象,当spring容器启动的时候,就会去加载这个配置⽂件,然后将这些对象给组装好以供外部访问者使⽤。

这⾥所说的IOC容器也叫spring容器。

由spring容器管理的对象统称为Bean对象。

Bean就是普通的java对象,和我们⾃⼰new的对象其实是⼀样的,只是这些对象是由spring去创建和管理的,我们需要在配置⽂件中告诉spring容器需要创建哪些bean对象,所以需要先在配置⽂件中定义好需要创建的bean对象,这些配置统称为bean定义配置元数据信息,spring容器通过读取这些bean配置元数据信息来构建和组装我们需要的对象。

1. 引⼊spring相关的maven配置2. 创建bean配置⽂件,⽐如bean xml配置⽂件3. 在bean xml⽂件中定义好需要spring容器管理的bean对象4. 创建spring容器,并给容器指定需要装载的bean配置⽂件,当spring容器启动之后,会加载这些配置⽂件,然后创建好配置⽂件中定义好的bean对象,将这些对象放在容器中以供使⽤5. 通过容器提供的⽅法获取容器中的对象,然后使⽤spring内部提供了很多表⽰spring容器的接⼝和对象,我们来看看⽐较常见的⼏个容器接⼝和具体的实现类。

Spring源码解析–AnnotationConfigApplicationContext。。。

Spring源码解析–AnnotationConfigApplicationContext。。。

Spring源码解析–AnnotationConfigApplicationContext。

Spring在BeanFactory基础上提供了⼀些列具体容器的实现,其中AnnotationConfigApplicationContext是⼀个⽤来管理注解bean的容器,从AnnotationConfigApplicationContext的实现结构图中可以看出:AnnotationConfigApplicationContext继承GenericApplicationContext这个通⽤应⽤上下⽂,GenericApplicationContext内部定义了⼀个DefaultListableBeanFactory实例,GenericApplicationContext实现了BeanDefinitionRegistry接⼝,所以可以通过AnnotationConfigApplicationContext实例注册bean defintion,然后调⽤refresh()⽅法来初始化上下⽂。

AnnotationConfigApplicationContext继承AbstractApplicationContext,AbstractApplicationContext提供了ApplicationContext的抽象实现。

下⾯通过⼀个⽰例分析AnnotationConfigApplicationContext的初始化过程:AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtensionConfig.class);构造函数:1//1. 初始化bean读取器和扫描器;2//调⽤⽗类GenericApplicationContext⽆参构造函数,初始化⼀个BeanFactory: DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory()3this();4//2.注册bean配置类5 register(annotatedClasses);6//3.刷新上下⽂7 refresh();8 }1. this() 初始化bean读取器和扫描器1public AnnotationConfigApplicationContext() {2//在IOC容器中初始化⼀个注解bean读取器AnnotatedBeanDefinitionReader3this.reader = new AnnotatedBeanDefinitionReader(this);4//在IOC容器中初始化⼀个按类路径扫描注解bean的扫描器5this.scanner = new ClassPathBeanDefinitionScanner(this);⽗类GenericApplicationContext部分代码:1public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {2private final DefaultListableBeanFactory beanFactory;34//初始化⼀个BeanFactory5public GenericApplicationContext() {6this.beanFactory = new DefaultListableBeanFactory();7 }89 …10 }2. register(annotatedClasses)注册bean配置类, AnnotationConfigApplicationContext容器通过AnnotatedBeanDefinitionReader的register⽅法实现注解bean的读取,具体源码如下:AnnotationConfigApplicationContext.java中register⽅法1//按指定bean配置类读取bean2public void register(Class<?>... annotatedClasses) {3for (Class<?> annotatedClass : annotatedClasses) {4 registerBean(annotatedClass);5 }6 }78public void registerBean(Class<?> annotatedClass) {9 doRegisterBean(annotatedClass, null, null, null);10 }1112//核⼼实现逻辑13 <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,14 @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {15//将Bean配置类信息转成容器中AnnotatedGenericBeanDefinition数据结构, AnnotatedGenericBeanDefinition继承⾃BeanDefinition作⽤是定义⼀个bean的数据结构,下⾯的getMetadata可以获取到该bean上的注解信息16 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);17//@Conditional装配条件判断是否需要跳过注册18if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {19return;20 }21//@param instanceSupplier a callback for creating an instance of the bean22//设置回调23 abd.setInstanceSupplier(instanceSupplier);24//解析bean作⽤域(单例或者原型),如果有@Scope注解,则解析@Scope,没有则默认为singleton25 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);26 //作⽤域写回BeanDefinition数据结构, abd中缺损的情况下为空,将默认值singleton重新赋值到abd27 abd.setScope(scopeMetadata.getScopeName());28 //⽣成bean配置类beanName29 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));30//通⽤注解解析到abd结构中,主要是处理Lazy, primary DependsOn, Role ,Description这五个注解31 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);32 //@param qualifiers specific qualifier annotations to consider, if any, in addition to qualifiers at the bean class level33 // @Qualifier特殊限定符处理,34if (qualifiers != null) {35for (Class<? extends Annotation> qualifier : qualifiers) {36if (Primary.class == qualifier) {37// 如果配置@Primary注解,则设置当前Bean为⾃动装配autowire时⾸选bean38 abd.setPrimary(true);39 }40 else if (Lazy.class == qualifier) {41 //设置当前bean为延迟加载42 abd.setLazyInit(true);43 }44else {45 //其他注解,则添加到abd结构中46 abd.addQualifier(new AutowireCandidateQualifier(qualifier));47 }48 }49 }50 //⾃定义bean注册,通常⽤在applicationContext创建后,⼿动向容器中⼀lambda表达式的⽅式注册bean,51 //⽐如:applicationContext.registerBean(UserService.class, () -> new UserService());52for (BeanDefinitionCustomizer customizer : definitionCustomizers) {53 //⾃定义bean添加到BeanDefinition54 customizer.customize(abd);55 }56//根据beanName和bean定义信息封装⼀个beanhold,heanhold其实就是⼀个 beanname和BeanDefinition的映射57 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);58 //创建代理对象59 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);60 // BeanDefinitionReaderUtils.registerBeanDefinition 内部通过DefaultListableBeanFactory.registerBeanDefinition(String beanName, BeanDefinition beanDefinition)按名称将bean定义信息注册到容器中,61 // 实际上DefaultListableBeanFactory内部维护⼀个Map<String, BeanDefinition>类型变量beanDefinitionMap,⽤于保存注bean定义信息(beanname 和 beandefine映射)62 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);63 }register⽅法重点完成了bean配置类本⾝的解析和注册,处理过程可以分为以下⼏个步骤:1. 根据bean配置类,使⽤BeanDefinition解析Bean的定义信息,主要是⼀些注解信息2. Bean作⽤域的处理,默认缺少@Scope注解,解析成单例3. 借助AnnotationConfigUtils⼯具类解析通⽤注解4. 将bean定义信息已beanname,beandifine键值对的形式注册到ioc容器中3. refresh()刷新上下⽂refresh⽅法在AbstractApplicationContext容器中实现,refresh()⽅法的作⽤加载或者刷新当前的配置信息,如果已经存在spring容器,则先销毁之前的容器,重新创建spring容器,载⼊bean定义,完成容器初始化⼯作,debug进源码可以看出AnnotationConfigApplicationContext容器是通过调⽤其⽗类AbstractApplicationContext的refresh()函数启动整个IoC容器完成对Bean定义的载⼊。

ORA-12519-手工加载spring配置文件导致数据库session无法释放的问题

ORA-12519-手工加载spring配置文件导致数据库session无法释放的问题
迅速打开PLSQL,检查数据库session,Select Count(1) From v$session t Where t.SCHEMANAME='XXX';
随着service的执行,session数在增加,没有减少的意思。是的,当时就是这样。
解决思路:这种错误出现在久经考验的框架当中,我心里是相当不安的,居然会有这种低级趣味的错误。整理思路开始分析:这段代码唯一与以前不同的地方就是,我们在web应用中,是通过容器加载提供bean的,只有容器启动的时候才会加载xml。那么重点就应该是关注XML的加载方式了。
问题现象:在做web应用时会碰到这种情况,某些地方无法通过web当中的ApplicationContext来获得springIOC容器提供的bean,比如提供给外界的webservice接口,这个时候就需要手工通过ClassPathXmlApplicationContext等方式来获取ApplicationContext,代码如下:
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext-*.xml");
IXXXService xxxservice = (IXXX描述的很清楚。通过DisposableBean或者指定destroy-method都能很好的释放单例对象。而prototype类型的对象需要客户端显式的指定释放,释放对象完全是客户端控制,spring不负责释放。
所以,要改善context的加载方式,尽量的少多次去加载,实在没办法的情况下,一定要记得关闭。
这里实验一把,将ApplicationContext改成AbstractApplicationContext,执行context.close()。结果出来了,session已被正常回收,真相渐渐浮出水面。

spring中AbstractApplicationContext讲解

spring中AbstractApplicationContext讲解

AbstractApplicationContextApplicationContext的抽象实现,这里采用了模版方法的设计模式,需要具体的子类去具体实现这些抽象方法。

这个类中,最重要的就是refresh()方法,虽然其中很多方法都需要子类去实现,但是,我们还是需要对其中调用的方法做一个详细的说明!1.protected void prepareRefresh() {this.startupDate = System.currentTimeMillis();synchronized (this.activeMonitor) {this.active = true;}if (logger.isInfoEnabled()) {("Refreshing " + this);}}●这个方法有个比较重要的地方,就是this,通过日志记录getClass(),我们发现,这个this并不是AbstractApplicationContext,而是ClassPathXmlApplicationContext(这个地方,在我以前的关于class的说明中有,一定要记住)!●再一个就是,当我()出来的结果让我有点意外,如下:Refreshingorg.springframework.context.support.ClassPathXmlApplicationContext@85 af80: display name [org.springframework.context.support.ClassPathXmlApplicationContext@8 5af80]; startup date [Tue Sep 28 11:38:55 CST 2010]; root of context hierarchy我们可以想象,不可能每个类都有startup date的东西,为什么会出现这样的情况呢?通过分析,我们发现,所有的java 类都是继承了object类,而这个object类中有个toString()方法,我们看看源代码:public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}从这里可以知道,在display name 之前的部分才应该是toString()应该显示的东西,到这里,我们就可以怀疑,是否是AbstractApplicationContext重写了这个toString()方法呢?往后看,果然发现是这样,代码如下:public String toString() {StringBuffer sb = newStringBuffer(ObjectUtils.identityToString(this));sb.append(": display name [").append(getDisplayName());sb.append("]; startup date [").append(newDate(getStartupDate()));sb.append("]; ");ApplicationContext parent = getParent();if (parent == null) {sb.append("root of context hierarchy");}else {sb.append("parent:").append(ObjectUtils.identityToString(parent));}return sb.toString();}注:()需要的参数是String类型的,如果带的参数不是String类型的,那么JAVA会自动给予转换,就相当于自动调用toString()方法!2.protected final void refreshBeanFactory() throws BeansException {// Shut down previous bean factory, if any.ConfigurableListableBeanFactory oldBeanFactory = null;synchronized (this.beanFactoryMonitor) {oldBeanFactory = this.beanFactory;}if (oldBeanFactory != null) {oldBeanFactory.destroySingletons();synchronized (this.beanFactoryMonitor) {this.beanFactory = null;}}// Initialize fresh bean factory.try {DefaultListableBeanFactory beanFactory =createBeanFactory();customizeBeanFactory(beanFactory);loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing XML document for application context [" + getDisplayName() + "]", ex);}}3.protected void loadBeanDefinitions(DefaultListableBeanFactorybeanFactory) throws IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// Configure the bean definition reader with this context's// resource loading environment.beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(newResourceEntityResolver(this));// Allow a subclass to provide custom initialization of the reader,// then proceed with actually loading the bean definitions.initBeanDefinitionReader(beanDefinitionReader);loadBeanDefinitions(beanDefinitionReader);}下面讲解在加载数据中很重要的类Resource及其衍生类:Spring中的org.springframework.core.io.Resource接口代表着物理存在的任何资源,其继承于org.springframework.core.io.InputStreamSource;其子类有如下几种:ByteArrayResource, ClassPathResource, DescriptiveResource, FileSystemResource, InputStreamResource, PortletContextResource, ServletContextResource, UrlResource 。

contextstartedevent contextrefreshedevent 顺序

contextstartedevent contextrefreshedevent 顺序

contextstartedevent contextrefreshedevent 顺序
在Spring框架中,`ContextStartedEvent`和`ContextRefreshedEvent`是两个与应用程序上下文生命周期相关的事件。

它们分别表示上下文启动和刷新的事件。

1. ContextStartedEvent(上下文启动事件):
-当使用`ConfigurableApplicationContext`接口的`start()`方法启动应用程序上下文时,将触发`ContextStartedEvent`。

-这个事件表示应用程序上下文已经启动,但是此时并不代表所有的bean都已经完全初始化和准备好使用。

2. ContextRefreshedEvent(上下文刷新事件):
-当应用程序上下文完成其初始化过程,所有的bean都被成功装载并且应用程序上下文准备好为客户端提供服务时,将触发`ContextRefreshedEvent`。

-这个事件表示应用程序上下文已经刷新,并且所有的bean都已经初始化完毕。

顺序上,通常情况下,`ContextStartedEvent`会在`ContextRefreshedEvent`之前发生。

启动上下文是在刷新之前的一个步骤,但请注意,这并不是绝对的,因为具体的执行顺序可能会受到配置和监听器的影响。

如果你在应用程序中使用了这两个事件,可以通过实现`ApplicationListener`接口,并在`onApplicationEvent`方法中处理这些事件,以确保你的逻辑按照期望的顺序执行。

Spring中的常见的9种设计模式

Spring中的常见的9种设计模式

Spring中的常见的9种设计模式1.简单⼯⼚(⾮23种设计模式中的⼀种)2.⼯⼚⽅法3.单例模式4.适配器模式5.装饰器模式6.代理模式7.观察者模式8.策略模式9.模版⽅法模式Spring中涉及的设计模式总结1.简单⼯⼚(⾮23种设计模式中的⼀种)实现⽅式:BeanFactory。

Spring中的BeanFactory就是简单⼯⼚模式的体现,根据传⼊⼀个唯⼀的标识来获得Bean对象,但是否是在传⼊参数后创建还是传⼊参数前创建这个要根据具体情况来定。

实质:由⼀个⼯⼚类根据传⼊的参数,动态决定应该创建哪⼀个产品类。

实现原理:bean容器的启动阶段:读取bean的xml配置⽂件,将bean元素分别转换成⼀个BeanDefinition对象。

然后通过BeanDefinitionRegistry将这些bean注册到beanFactory中,保存在它的⼀个ConcurrentHashMap中。

将BeanDefinition注册到了beanFactory之后,在这⾥Spring为我们提供了⼀个扩展的切⼝,允许我们通过实现接⼝BeanFactoryPostProcessor 在此处来插⼊我们定义的代码。

典型的例⼦就是:PropertyPlaceholderConfigurer,我们⼀般在配置数据库的dataSource时使⽤到的占位符的值,就是它注⼊进去的。

容器中bean的实例化阶段:实例化阶段主要是通过反射或者CGLIB对bean进⾏实例化,在这个阶段Spring⼜给我们暴露了很多的扩展点:各种的Aware接⼝,⽐如 BeanFactoryAware,对于实现了这些Aware接⼝的bean,在实例化bean时Spring会帮我们注⼊对应的BeanFactory的实例。

BeanPostProcessor接⼝,实现了BeanPostProcessor接⼝的bean,在实例化bean时Spring会帮我们调⽤接⼝中的⽅法。

java+context用法

java+context用法

Java中的"context"通常指的是上下文,它可以表示程序运行时的环境或状态。

在不同的Java 框架和库中,"context"的具体用法可能有所不同,下面列举一些常见的用法:1. Web应用中的上下文:在Java Web应用中,"context"通常指的是ServletContext对象,它代表了整个Web应用程序的上下文。

通过ServletContext对象,可以获取Web应用的初始化参数、属性、资源等。

例如:ServletContext context = getServletContext();String appName = context.getServletContextName();2. Spring框架中的上下文:在Spring框架中,"context"指的是ApplicationContext对象,它是Spring IoC容器的核心接口。

通过ApplicationContext对象,可以获取Spring容器中管理的Bean对象、配置信息等。

例如:ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); MyBean myBean = (MyBean) context.getBean("myBean");3. Android应用中的上下文:在Android应用中,"context"指的是Context对象,它代表了应用程序环境的信息,包括应用程序的资源、类加载器、包名等。

通过Context对象,可以访问应用程序的资源、启动Activity、发送广播等。

例如:Context context = getApplicationContext();Intent intent = new Intent(context, MyActivity.class);context.startActivity(intent);。

SpringBoot启动流程(一)SpringApplication类的构造函数

SpringBoot启动流程(一)SpringApplication类的构造函数

SpringBoot启动流程(一)SpringApplication类的构造函数SpringApplication类是SpringBoot启动流程的核心类之一,它负责启动Spring应用程序。

在本文中,我们将详细讨论SpringApplication类的构造函数,并深入了解其在应用程序启动过程中的重要作用。

SpringApplication类的构造函数用于创建一个新的SpringApplication实例,它接收一个或多个参数。

具体来说,SpringApplication类的构造函数有两个重要的参数:一个是主要配置类,另一个是一组字符串参数。

另一个重要的参数是一组字符串参数。

这些字符串参数通常用于传递命令行参数,用于配置应用程序的行为。

在构造函数中,我们可以将这些字符串参数传递给SpringApplication,以便在应用程序启动时使用它们。

一旦创建了SpringApplication实例,我们可以调用其run方法来启动应用程序。

run方法是SpringBoot启动流程的关键方法,在应用程序启动过程中执行一系列的操作。

首先,run方法会创建一个SpringApplicationRunListeners列表,并使用SpringFactoriesLoader类加载运行监听器。

运行监听器是一种扩展机制,允许我们以插件形式添加自定义逻辑。

监听器可以在应用程序启动的各个阶段介入,并执行特定的任务。

例如,我们可以编写一个监听器,用于在应用程序启动时初始化数据库连接池。

接下来,run方法会创建一个SpringBootExceptionReporter实例,并在发生相关异常时使用它。

SpringBootExceptionReporter是一个接口,用于处理应用程序启动过程中的异常。

我们可以自定义一个实现,以便在异常发生时采取适当的措施。

然后,run方法会创建一个ConfigurableEnvironment实例,并将其与主要配置类关联起来。

SpringCloudbootstrap.yml和application.yml加载原理

SpringCloudbootstrap.yml和application.yml加载原理

SpringCloudbootstrap.yml和application.yml加载原理Spring Cloud 官⽅⽂档:https://cloud.spring.io/spring-cloud-static/spring-cloud.html⼀个Spring Cloud的操作是通过创建“bootstrap”context开始的,它是main application最上层的parent context。

开箱机⽤,它负责载⼊来⾃于外部的配置信息(properties),同时在本地解码外部配置⽂件的properties。

所有Spring应⽤程序都是由2个Context共享来⾃外部properties的环境Environment。

Bootstrap properties在被加载时具有最⾼的优先权,所以默认情况下bootstrap properties不会被本地配置覆盖。

bootstrap context 使⽤不同的⽅式定位外部配置信息,⽽不是像main application context那样,所以你可以使⽤bootstrap.yml 代替application.yml or application.properties, 最好将外部配置交给bootstrap,并与main context分开。

如果你的application在server端有任何特殊的配置,最好是将设置到bootstrap.yml内,因为bootstrap.yml 不会被本地配置所覆盖。

你也完全可以通过设置系统属性(system properties)spring.cloud.bootstrap.enabled=false, 来禁⽤bootstrap process。

bootstrap.yml 和application.yml 都可以⽤来配置参数bootstrap.yml可以理解成系统级别的⼀些参数配置,这些参数⼀般是不会变动的application.yml 可以⽤来定义应⽤级别的,如果搭配spring-cloud-config使⽤ application.yml⾥⾯定义的⽂件可以实现动态替换Bootstrap.yml(bootstrap.properties)在application.yml(application.properties)之前加载,就像application.yml⼀样,但是⽤于应⽤程序上下⽂的引导阶段。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Spring中ApplicationContext加载机制。

加载器目前有两种选择:ContextLoaderListener和ContextLoaderServlet。

这两者在功能上完全等同,只是一个是基于Servlet2.3版本中新引入的Listener接口实现,而另一个基于Servlet接口实现。

开发中可根据目标Web容器的实际情况进行选择。

配置非常简单,在web.xml中增加:<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>或:<servlet><servlet-name>context</servlet-name><servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class><load-on-startup>1</load-on-startup></servlet>通过以上配置,Web容器会自动加载/WEB-INF/applicationContext.xml初始化ApplicationContext实例,如果需要指定配置文件位置,可通过context-param加以指定:<context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/myApplicationContext.xml</param-value></context-param>配置完成之后,即可通过WebApplicationContextUtils.getWebApplicationContext方法在Web应用中获取ApplicationContext引用。

如:ApplicationContext ctx=WebApplicationContextUtils.getWebApplicationContext(); LoginAction action=(LoginAction)ctx.getBean("action");=============================Spring中WebApplicationContext的研究ApplicationContext是Spring的核心,Context我们通常解释为上下文环境,我想用“容器”来表述它更容易理解一些,ApplicationContext则是“应用的容器”了,Spring把Bean放在这个容器中,在需要的时候,用getBean方法取出,虽然我没有看过这一部分的源代码,但我想它应该是一个类似Map的结构。

在Web应用中,我们会用到WebApplicationContext,WebApplicationContext继承自ApplicationContext,先让我们看看在Web应用中,怎么初始化WebApplicationContext,在web.xml中定义:<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</list ener-class></listener><!-- OR USE THE CONTEXTLOADERSERVLET INSTEAD OF THE LISTENER<servlet><servlet-name>context</servlet-name><servlet-class>org.springframework.web.context.ContextLoaderServlet</servle t-class><!-- 自动启动 --><load-on-startup>1</load-on-startup></servlet>-->可以看出,有两种方法,一个是用ContextLoaderListener这个Listerner,另一个是ContextLoaderServlet这个Servlet,这两个方法都是在web应用启动的时候来初始化WebApplicationContext,我个人认为Listerner要比Servlet更好一些,因为Listerner 监听应用的启动和结束,而Servlet得启动要稍微延迟一些,如果在这时要做一些业务的操作,启动的前后顺序是有影响的。

那么在ContextLoaderListener和ContextLoaderServlet中到底做了什么呢?以ContextLoaderListener为例,我们可以看到public void contextInitialized(ServletContextEvent event) {this.contextLoader = createContextLoader();this.contextLoader.initWebApplicationContext(event.getServletContext());}protected ContextLoader createContextLoader() {return new ContextLoader();}ContextLoader是一个工具类,用来初始化WebApplicationContext,其主要方法就是initWebApplicationContext,我们继续追踪initWebApplicationContext这个方法(具体代码我不贴出,大家可以看Spring中的源码),我们发现,原来ContextLoader是把WebApplicationContext(XmlWebApplicationContext是默认实现类)放在了ServletContext中,ServletContext也是一个“容器”,也是一个类似Map的结构,而WebApplicationContext在ServletContext中的KEY就是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,我们如果要使用WebApplicationContext则需要从ServletContext取出,Spring提供了一个WebApplicationContextUtils类,可以方便的取出WebApplicationContext,只要把ServletContext传入就可以了。

上面我们介绍了WebApplicationContext在Servlet容器中初始化的原理,一般的Web应用就可以轻松的使用了,但是,随着Struts的广泛应用,把Struts和Spring整个起来,是一个需要面对的问题,Spring本身也提供了Struts的相关类,主要使用的有org.springframework.web.struts.ActionSupport,我们只要把自己的Action继承自ActionSupport,就是可以调用ActionSupport中getWebApplicationContext()的方法取出WebApplicationContext,但这样一来在Action中,需要取得业务逻辑的地方都要getBean,看上去不够简洁,所以Spring又提供了另一个方法,用org.springframework.web.struts.ContextLoaderPlugIn,这是一个Struts的Plug,在Struts启动时加载,对于Action,可以像管理Bean一样来管理,在struts-config.xml中Action的配置变成类似下面的样子<action attribute="aForm" name="aForm" path="/aAction" scope="request"type="org.springframework.web.struts.DelegatingActionProxy"><forward name="forward" path="forward.jsp" /></action>注意type变成了org.springframework.web.struts.DelegatingActionProxy,之后我们需要建立action-servlet.xml这样的文件,action-servlet.xml符合Spring的spring-beans.dtd标准,在里面定义类似下面的<bean name="/aAction" class="com.web.action.Aaction" singleton="false"><property name="businessService"><ref bean="businessService"/></property></bean>com.web.action.Aaction是Action的实现类,businessService是需要的业务逻辑,Spring 会把businessService注入到Action中,在Action中只要写businessService的get和set方法就可以了,还有一点,action的bean是singleton="false",即每次新建一个实例,这也解决了Struts中Action的线程同步问题,具体过程是当用户做“/aAction”的HTTP请求(当然应该是“/aAction.do”),Struts会找到这个Action的对应类org.springframework.web.struts.DelegatingActionProxy,DelegatingActionProxy是个代理类,它会去找action-servlet.xml文件中“/aAction”对应的真正实现类,然后把它实例化,同时把需要的业务对象注入,然后执行Action的execute方法。

相关文档
最新文档