文档章节

Spring 源码随便看看

 陆大侠
发布于 2015/10/31 20:05
字数 981
阅读 147
收藏 1

书籍: Spring in action 第四版及源码,,,spring 源码深度解析(郝佳)

ClassPathXmlApplicationContext context = 
    ClassPathXmlApplicationContext(
        );

从上面这句调试进入,Spring的源码:

构造函数中,将文件的位置存放到 

setConfigLocations(configLocations);
if (refresh) { //这个变量默认为 true
   refresh();
}

refresh()这个函数,做了很多事情,依次为:

(.) {
   prepareRefresh();  // 这个方法里面处理了properties文件

   ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 将 this.beanFactory 初始化 为 DefaultListableBeanFactory,这个类很核心。
      // 里面有个关键的方法 loadBeanDefinitions(beanFactory); 将所有的BeanDefinition加载到beanFactory 
   
   //里面设置了beanFactory的ClassLoader,BeanExpressionResolver等等
   //还可能注册几个特殊的bean,比如envirment,systemProperties等等
   prepareBeanFactory(beanFactory);

   {
       //这是beanFactory的后处理器,这里可以修改beanDefinition的信息
      postProcessBeanFactory(beanFactory);

      //这里是调用了beanFactory的后处理器
      invokeBeanFactoryPostProcessors(beanFactory);
        
        //注册bean的后处理器
      registerBeanPostProcessors(beanFactory);

      //初始化国际化信息
      initMessageSource();

        //事件广播器的初始化
      initApplicationEventMulticaster();
      
      //Initialize other special beans in specific context subclasses.
      onRefresh();

      //注册事件的监听者
      registerListeners();

      // Instantiate all remaining (non-lazy-init) singletons.
      //实例化所有的非延迟加载的单例bean, 会遍历bd的列表,如果是singleton,就会继续往下走
      //很深的地方有个doGetBean方法,再进去里面很多前后处理和检查,然后
      // singletonObject = singletonFactory.getObject(); 把当前这个name的bean实例化,这里面也会同时加载那些需要依赖的bean
      // 最后 addSingleton(beanName, singletonObject);把实例化的bean 加入到了缓存里面
      // 当我们获取这个bean的时候,就会从缓存里面读取
      finishBeanFactoryInitialization(beanFactory);
      //发布完成事件,注册一个lifecycleProcessor
      finishRefresh();
   }

   (BeansException ex) {
      .warn(, ex);

      destroyBeans();

      cancelRefresh(ex);

      ex;
   }
}

AbstractXmlApplicationContext的loadBeanDefinitions方法,处理将xml配置的bean转化为BeanDefinition

DefaultBeanDefinitionDocumentReader类的parseBeanDefinitions
这个对象是reader对象是被ApplicationContext对象所持有

很深的地方,有个parseBeanDefinitions 这个方法,把xml的节点传进入,并进行解析,最后加入到一个delegate对象上,这个对象的类型是 BeanDefinitionParseDelegate.

1 .这个地方,会区分是默认的Bean,import等等节点,还是Aspect等等其他custom节点,会做不同的解析。

最后,将ConfigurableListableBeanFactory将BeanDefinition注册到自己的缓冲中,beanDefinitionNames和

beanDefinitionMap.

2. NamespaceHandler (org.springframework.beans.factory.xml) 定制化的节点的handle,比如AopNamespaceHandler (org.springframework.aop.config) 这个是处理 aop的。

CacheNamespaceHandler (org.springframework.cache.config) 

有这样一个类 ConfigBeanDefinitionParser (org.springframework.aop.config) , 对aop下面的节点做了解析。

通常在aop被解析以后会有以下的一些类,被注册到BeanDefinitionMap中,将实现以后的Aop做准备。

 [org.springframework.aop.aspectj.AspectJExpressionPointcut]  表达式切点 [org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator] 这个类建立代理的创建者[org.springframework.aop.aspectj.AspectJPointcutAdvisor]  切点顾问 如before, after, around等五种类型

3。下面来看看,aop在bean实例化的时候,如何被代理实现的。

AbstractBeanFactory 一般这个类实现了Bean的实例化

在上面说的doGetBean方法进去,

AbstractAutowireCapableBeanFactory 这个类里面
最后,这个对象的doCreateBean方法返回了一个AspectJAwareAdvisorAutoProxyCreator的实例。
AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation) 这个类及其父类,实现了查找advices和wrap bean的工作
getAdvicesAndAdvisorsForBean 这里会查找到相关的AspectJPointcutAdvisor对象,每个advisor持有一个advice. 比如,before,around等等advice.
AbstractAutowireCapableBeanFactory的applyBeanPostProcessorsAfterInitialization方法进去,就是
bean的后处理,最后到ProxyCreator的wrapIfNecessary去包装了bean实例。
最终AbstractAutoProxyCreator的createProxy方法,包装bean实例。
org.springframework.aop.framework.ProxyFactory: 这个类,有很多属性,比如interface,advice,targetSource等等,被赋值之后,调用了DefaultAopProxyFactory的createAopProxy方法创建代理。
下面是最后的这个方法:
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
   if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
      Class<?> targetClass = config.getTargetClass();
      if (targetClass == null) {
         throw new AopConfigException("TargetSource cannot determine target class: " +
               "Either an interface or a target is required for proxy creation.");
      }
      if (targetClass.isInterface()) {
         return new JdkDynamicAopProxy(config);
      }
      return new ObjenesisCglibAopProxy(config);
   }
   else {
      return new JdkDynamicAopProxy(config);
   }
}

包装后的代理对象为JdkDynamicAopProxy,还有CglibAopProxy(如果对象不是接口)。
当方法调用时候,会进入JdkDynamicAopProxy对象的invoke方法
实例化了一个ReflectiveMethodInvocation, 最后一层一层调用到 反射类Method的invoke方法,进入了本地代码区域。


© 著作权归作者所有

粉丝 2
博文 54
码字总数 18787
作品 0
浦东
私信 提问
Spring Boot是如何实现自动配置的

Spring Boot 是 Spring 旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准化的应用。Spring Bo...

技术小能手
2018/07/09
0
0
Spring Boot 自动配置的 “魔法” 是如何实现的?

原文出处:sylvanassun Spring Boot是Spring旗下众多的子项目之一,其理念是约定优于配置,它通过实现了自动配置(大多数用户平时习惯设置的配置作为默认配置)的功能来为用户快速构建出标准...

sylvanassun
2018/06/10
0
0
openshift上使用jersey+spring无果,果断转回springmvc

openshift上使用jersey+spring无果,果断转回springmvc –20130328 今天使用jersey+spring,成功在本机测试成功。 源码见“jersey-spring”; 我上次写过了能在openshift上部署jersey1.8,见...

LiangShao
2013/03/28
378
0
Spring源码学习笔记-1-Resource

打算补下基础,学习下Spring源码,参考书籍是《Spring源码深度解析》,使用版本是Spring 3.2.x,本来想试图用脑图记录的,发现代码部分不好贴,还是作罢,这里只大略记录下想法,不写太细了 ...

zypy333
2018/12/15
29
0
【Spring】BeanFactory解析bean详解

在该文中来讲讲Spring框架中BeanFactory解析bean的过程,该文之前在小编原文中有发表过,要看原文的可以直接点击原文查看,先来看一个在Spring中一个基本的bean定义与使用。 Spring配置文件r...

weknow
2017/04/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
5
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
8
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
10
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
6
0
PHP+Ajax微信手机端九宫格抽奖实例

PHP+Ajax结合lottery.js制作的一款微信手机端九宫格抽奖实例,抽奖完成后有收货地址添加表单出现。支持可以设置中奖概率等。 奖品列表 <div class="lottery_list clearfix" id="lottery"> ......

ymkjs1990
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部