spring源码解读感想

1.IOC

控制反转,依赖注入,spring简化了ejb形式的编码方式,由原本强依赖的对象关系,变成简单pojo对象,将控制权交给容器,再反将依赖关系注入到对象中。

如xml配置文件,而spring IOC模块做到的就是将多形式的beanDefinition注入到容器中。在这里要提一下beanFactory, 作为一个最上层的接口,有多个方法,最主要的是getBean(String name,Class<T> requiredType) ,这个接口只是定义了整个容器的基础功能,其下一系列的接口,可以使用不同的Bean的检索方法,很方便从IOC容器中得到需要的Bean,从而忽略具体的Ioc容器的实现。

有一个具体的XmlBeanFactory,使用了DefaultListableBeanFactory 作为基类,内部封装了io流读取xml文件获得资源信息,载入和注册bean.

//获取资源

ClassPathResource res = new ClassPathResource(“bean.xml”);

//创建bean

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

//创建资源读取器,然后通过回调配置给factory

XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);

reader.loadBeanDefinitions(res);

其实大部分的factory都是只实现了基础方法。而spring新增了很多为了应对各个情况的类。如applicationContext 的设计,除了实现上层接口,也继承了很多功能类。

比如FileSystemXmlApplicationContext有一段:

getResourceByPath(String path){

if (path !=null && path.startWith(“/”)){

path = path.substring(1);

}

return new FileSystemResource(path);

}

后续详细就不展开了,简单说这个类就实现了从文件系统中读取XML形式的beanDefinition。

———————–2016/10/14

这几天继续再看ioc部分的源码解读。

接着上面的说,在spring通过xml形式拿到beanDefinition以后会将bean注册到容易中,所谓的注册就是通过map的形式把bean name和beanDefinition绑定在一块。

而真正的依赖注入还没开始。

首先需要用户第一次向容器获取bean,在BeanFactory接口中有个最为关键的getBean方法,是触发依赖注入发生的地方,而依赖注入分为两部分,第一是createBean(),会根据拿到的beanDefinition定义的要求来生成对应bean对象。还会对bean初始化进行处理,比如实现了在beanDefinition中的init-method属性,后置处理器等等。

接着源码往后走,在AbstractAutowireCapableBeanFactory类中可以看到整个createBean的过程和两个方法相关,一个是

createBeanInstance(beanName, mbd, args);

一个是

populateBean(beanName, mbd, instanceWrapper);

而createBeanInstance对于bean生成方式多样,有工厂方法生成,有容器的autowire特性生成,都是由相关beanDefinition来指定。这是实例化bean对象的整个流程,具体生成设计构造器,工厂方法,cglib等不进行赘述。完成这些后,怎样把bean对象的依赖关系设置好,完成整个依赖注入过程,这些都是在populateBean方法中完成。

具体的注入是在beanWrapper的setPropertyValues中实现的,完成是在子类BeanWrapperImpl。其中有对array,list,map,各property的注入。

ps:关于factoryBean的用法,因为是用来生产特定形式的bean,即在<bean id=”a” factory-bean=””,factory-method=”” class=null>中 class指定必须为空。

而例如CarFactoryBean 是implements FactoryBean<Object>的,其中的getObejct(),返回指定的类对象。

————————-2016/10/21

关于spring AOP的实现原理,首先是proxyFactoryBean的实现过程。xml文件配置好

<bean id="CustomerService" class="com.talkyun.share.yifeng.test.CustomerService">
    <property name="name" value="caori"/>
    <property name="url" value="yifeng"/>
</bean>

<bean id="TestBeforeMethod" class="com.talkyun.share.yifeng.test.TestBeforeMethod"/>

<bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="CustomerService" />
    <property name="interceptorNames">
        <list>
            <value>TestBeforeMethod</value>
        </list>
    </property>
</bean>

其中ProxyFactoryBean是spring已经实现好的代理类。target属性是给其父类advisedSupport用来获取目标类的配置信息。

interceptorNames是获得通知Advisor链,实际取得通知器的过程也就是容器的getBean方法,通过对ioc容器的回调来完成,最后加入到拦截器链中。

完成了这一步之后就是生成具体的代理类。这里要通过AopProxyFactory来完成,流程是ProxyFactoryBean->父类ProxyCreatorSupport中,默认用的

/**  * Create a new ProxyCreatorSupport instance.  */ public ProxyCreatorSupport() {
   this.aopProxyFactory = new DefaultAopProxyFactory();
}

这里的this.aopProxyFactory的this是因为

ProxyCreatorSupport//原本就是AdvisedSupport的子类,而AdvisedSupport是借助AopProxyFactory来生成代理对象的

而在DefaultAopProxyFactory中会根据获取到的target配置信息是否有接口来决定代理形式是jdk的proxy还是cglib

@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);
   }
}

—————————10.24

    原文作者:Spring Cloud
    原文地址: https://blog.csdn.net/FewMore/article/details/52813643
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞