
Spring使用 基本的JavaBean 来完成以前只可能由EJB完成的事情,是个分层架构。Spring创建bean都需要通过 读取 、 解析 、 校验配置文件, 然后注册创建成Bean。 Spring是一个Bean容器 , 主要作用是替我们管理bean对象 (简单的Java类对象的生命周期)。不管框架如何强大,还是需要我们程序员来告诉其一些必要信息的(比如要 管理的bean对象的类相关信息、是否开启组件扫描 等),这些我们称之为对 Spring框架的配置 ,目前主流的配置方式是 通过使用配置文件或注解。
Spring中最核心的两个类: DefaultListableBeanFactory、XmlBeanDifinitionReader。DefaultListableBeanFactory 是整个bean加载的核心部分,是Spring注册及加载bean的默认实现 。XmlBeanDefinitionReader 主要使用reader属性对资源文件进行读取和注册。
XML配置文件读取是Spring中重要的功能,大部分Spring大部分功能都是 以配置作为切入点 。 XmlBeanFactory 继承自 DefaultListableBeanFactory ,而对于 DefaultListableBeanFactory 不同的地方其实是在 XmlBeanFactory 中使用了自定义的XML读取器 XmlBeanDefinitionReader ,主要用于从XML文档中读取 BeanDefinition, 实现了个性化的 BeanDefinitionReader 读取, DefaultListableBeanFactory 继承了 AbstractAutowireCapableBeanFactory 并实现了 ConfigurableListableBeanFactory 以及 BeanDefinitionRegistry 接口。
Spring的配置文件读取是通过ClasaPathResource进行封装的 ,如:new ClassPathResource("beanxml")。在java中, 将不同来源的资源的读取逻辑抽象成URL ,通过注册不同的 handler来处理。 一般handler的类型使用不同的前缀,URL没有默认定义相对的path路径,也 没有提供相关方法对资源进行检查 ,顾Spring对其内部需要使用到的资源做了属于自己的抽象结构, 用Resource接口来封装底层资源。
Resource 接口继承 InputStreamSource(封装了任何能返回InputStream的类)。
Resource接口抽象了所有Spring内部使用到的底层资源 ,首先它定义了3个能判断当前资源状态的方法: 存在性(exists)、可读性(isReadable)、是否处于打开状态(isOpen) 。有了Resource接口便可以对所有资源进行统一处理。 ClassPathResource 中的实现是通过class或 classLoader 提供的底层方法进行调用。以此完成对配置文件资源的封装。
当通过Resource相关类完成了对配置文件进行封装,接下来由 XmlBeanDefinitionReader 完成对配置文件的读取工作。
XML文件的验证模式有两种:DTD、XSD(XML Schema)
DTD即文档类型定义, 是一种XML约束模式语言,是XML文件的验证机制 。是一种保证XML文档格式正确的有效方法, 可以通过比较XML文档和DTD文件来查看文档是否符合规范,元素和标签的使用是否正确 。一个DTD文档包含:元素的定义规则、元素间关系的定义规则、元素可使用的属性、可使用的实体或符号规则。 要使用DTD验证模式需要在XML文件的头部声明。
XML Schema语言就是XSD。 XML Schema描述了XML文档的结构。可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其要求。也可以 通过XML Schema指定一个XML文档所允许的结构和内容 。XML Schema本身也是一个XML文档,符合XML语法结构,可以用通用的XML解析器解析它。
使用XML Schema文档对XML实例进行校验,要声明名称空间和指定该名称空间所对应的XML Schema文档存储位置 。通过schemaLocation属性来指定名称空间所对应的XML Schema文档的存储地址(1、名称空间URL;2、该名称空间所标识的XML Schema文件地址或URL地址)。
另外验证模式通过 XmlBeanDefinitionReader 中的setValidationMode方法进行设定。而 Spring 用来检测验证模式的方法实际上就是判断是否包含 DOCTYPE ,如果包含就是 DTD ,否则就是 XSD 。
XML文件经过验证模式,交由DocumentLoader进行解析成对应的 Document。 而解析的过程中存在这么一环节:(EntityResolver) 根据声明去寻找对应的DTD定义,以便对文档进行验证认证 。也可以通过setEntityResolver设置DTD定义。EntityResolver它用来接收两个参数publicId和systemId,xsd格式文件通常publicId为null。而对于不同的验证模式采用不同的解析器进行解析,并把文件转换成Document文件,用于提取及注册bean。
Document 文件通过 BeanDefinitionDocumentReader 进行内部逻辑处理,并提取root用于作为参数继续完成BeanDefinition的注册。
一 什么是Spring
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架
二 如何在程序中获取Spring配置的bean呢
方法一 在初始化时保存ApplicationContext对象
代码
ApplicationContext ac = new FileSystemXmlApplicationContex( applicationContext xml ); ac getBean( beanId );
ApplicationContext ac = new FileSystemXmlApplicationContex( applicationContext xml );
ac getBean( beanId );说明 这种方式适用于采用Spring框架的独立应用程序 需要程序通过配置文件手工初始化Spring的情况
方法二 通过Spring提供的工具类获取ApplicationContext对象
代码
import sprntext support WebApplicationContextUtils; ApplicationContext ac = WebApplicationContextUtils getRequiredWebApplicationContext(ServletContext sc) ApplicationContext ac = WebApplicationContextUtils getWebApplicationContext(ServletContext sc) ac getBean( beanId ); ac getBean( beanId ); import sprntext support WebApplicationContextUtils; ApplicationContext ac = WebApplicationContextUtils getRequiredWebApplicationContext(ServletContext sc) ApplicationContext ac = WebApplicationContextUtils getWebApplicationContext(ServletContext sc) ac getBean( beanId ); ac getBean( beanId );方法三 继承自抽象类ApplicationObjectSupport
说明 抽象类ApplicationObjectSupport提供getApplicationContext()方法 可以方便的获取到ApplicationContext Spring初始化时 会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入
方法四 继承自抽象类WebApplicationObjectSupport
说明 类似方法三 调用getWebApplicationContext()获取WebApplicationContext
方法五 实现接口ApplicationContextAware
lishixinzhi/Article/program/Java/ky/201311/28587
spring 怎么获取webxml中的context Spring配置文件在类路径下面 在Spring的java应用程序中,一般我们的Spring的配置文件都是放在放在类路径下面(也即编译后会进入到classes目录下)。 以下的项目,因为是用maven管理的
这样xml中配置的bean的属性就会被注入配置文件里面对应的值
首先xml中的bean会在扫描的过程中封装成BeanDefinition对象,property标签会被弄成一个ProprotyValue的集合放在BeanDefinition的ProprotyValues变量中,所以在xml解析完成之后的BeanDefinition的ProprotyValues变量是这样的
上节PropertySourcesPlaceholderConfigurer这个类收集了environment配置信息和本地配置信息,并把它放在了PropertySourcesPropertyResolver的propertySources属性中
最后创建了一个StringValueResolver对象会调用PropertySourcesPropertyResolver来处理配置信息的替换
接下来就是取出所有的BeanDefinition,看看beanDefinition中的属性中是否有${}表达式,有的话就替换
很多的属性都可以用${}来引用配置信息
重点看看属性是如何被替换的
在BeanDefinitionVisitorresolveValue方法中,String类型的走这
最终会调到PropertySourcesPlaceholderConfigurer创建的StringValueResolver匿名对象的实现方法中
这个匿名对象实现的方法又会调用PropertySourcesPropertyResolver来替换值,前面有提到所有的配置信息都在PropertySourcesPropertyResolverpropertySources中,那么接下来的工作就是从这个容器中找到对应的配置信息的key所对应的value
这里在入参时会创建一个PlaceholderResolver的匿名对象,实现的resolvePlaceholder方法将会调用PropertySourcesPropertyResolvergetPropertyAsRawString()
最后返回了被替换成对应配置信息的值
这里就会调用前面创建的匿名对象的实现方法,方法体重会调用调用PropertySourcesPropertyResolvergetPropertyAsRawString(),去用key获取对应的配置信息
PropertySourcesPropertyResolvergetPropertyAsRawString()
PropertiesPropertySource对象内部有name,和source,source是一个泛型,当前类型为Properties,PropertiesPropertySource需要实现getProperty方法,其实就是从source中获取属性值
最后调到了Properties类的get方法,返回value
对每个beanDefination都这样 *** 作过一遍
注意这个StringValueResolver的resolveStringValue会调用PropertySourcesPropertyResolver的方法来处理配置信息的替换,PropertySourcesPropertyResolver持有了所有的配置信息。 那么后面@Value的解析也将StringValueResolver来完成
@Value的解析工作是在Bean实例化后,属性注入的时候从配置文件找出并设置进去的
populateBean方法
只有string类型的才能@Value注解,才需要处理
又是这个容器,之前PropertySourcesPlaceholderConfigurer的doProcessProperties放进去的StringValueResolver
最后又会回到这个地方解析并注入值,和xml方式获取配置信息是一样的
找到对应的配置信息之后,反射设置这个属性的值
不用配置xml,直接java代码实现,参考代码如下:public class GetApplicationContext {private static class ApplicationContextHolder {// 单例变量private static ApplicationContext AC = new FileSystemXmlApplicationContext("classpath:applicationContextxml");}// 私有化的构造方法,保证外部的类不能通过构造器来实例化。private GetApplicationContext() {}// 获取单例对象实例public static ApplicationContext getInstance() {if (ApplicationContextHolderAC == null) {ApplicationContextHolderAC = new FileSystemXmlApplicationContext("classpath:applicationContextxml");}return ApplicationContextHolderAC;}}获取所有spring自动装配的bean://获取spring装配的bean个数GetApplicationContextgetInstance()getBeanDefinitionNames()length;//逐个打印出spring自动装配的bean。根据我的测试,类名第一个字母小写即bean的名字for(int i=0;i<33;i++){Systemoutprintln( GetApplicationContextgetInstance()getBeanDefinitionNames()[i]);}然后通过下面的代码获取到spring注解装配的bean供自己使用:StorageReturnService ossService = (StorageReturnService) GetApplicationContextgetInstance()getBean("storageReturnServiceImpl");怎样获取 spring 已经注解的bean
以上就是关于Spring源码解析(一)- 容器的基本实现全部的内容,包括:Spring源码解析(一)- 容器的基本实现、Java中如何获取Spring中配置的bean、spring web中control怎样获取xml中的bean等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)