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