IOC:
ioc要分为资源(url,filesystem,xml即classpath等)的定位、解析、注册和ioc这么四个部分。
资源的定位:refresh()-》obtainfreshbeanfactory()-》refreshfactory()-》loadbeandefinitions(factory)-》(设置beandefinitionreader,然后使用beandefinitionreader加载)-》getConfigResources()-》reader.loadbeandefinitions()-》loadbeandefinitions(resource)-》将资源文件转为inputstream的io流,设置encoding方式,载入资源。
解析:doc = loaddocument()-》registerbeandefinitions()。先把xml文件转换为DOM对象,由documentloader实现。然后再将doc解析为beandefinition。在registerbeandefinitions()中具体实现了解析过程。
先解析<beans>,对里面的import、alias和bean标签进行解释。重点解析bean标签。处理bean的id、name、别名等属性,然后对description、meta、lookup、构造方法、replace-method进行设置解析,然后重点解析里面的propertyelements,<property>。得到ref、value和list。然后对其中的list进行parsepropertysubelement()解析,后面就是递归调用。(这一段写的很乱)
注册:registerbeandefinition()。注册分为两个部分。注册beandefinition和注册别名。其实就是向容器里面的map<string name, beandefinition>里面进行添加。
ioc:依赖注入在一下两种情况发生:(1)用户第一次通过getbean方法向ioc容器索要bean时(2)当用户在bean定义资源中为《bean》元素配置了lazy-init属性,这只对单例的对象有效。就会在refresh里面的finishbeanfactoryinitialization()对其进行预实例化。
ioc过程分为三步:创建实例,配置属性和初始化。
创建实例:分为三种情况,工厂方法和参数匹配的构造方法,这个就调用工厂方法或者相应的构造方法进行创建实例。还有就是调用无参的构造方法,通过jdk反射或者cglib的方法进行创建实例。
配置属性:属性分为需要进行解析和不需要解析的两种。如果不需要解析,就直接进行复制,需要进行解析的,比如引用类型,还用通过反射和内省对属性进行配置。(比较复杂)
初始化:initializebean()-{applybeanpostprocessorsbeforeinitialization();invokeinitmethods();applybeanpostprocessorsafterinitialization();}其中中间就是使用反射进行初始化的方法,最后一个方法和aop紧密相关。第一个方法和第三个方法与后置处理器相关。
至此大体的ioc流程就结束了。
aop:
分为两个大的步骤:1.将我们配置的aop配置成beandefinition,并设置在容器里面。等待我们使用。2.动态生成代理对象。
第一个步骤:发生在DefaultBeanDefinitionDocumentReader的parseBeanDefinitions方法,因为<aop:cofig>标签不是默认的namespace,所以就使用parsecustomelement()。具体就是使用相应的namespace的namespacehandler把<aop:config>/<aop:aspect>/<aop:pointcut>/<aop:before>/<aop:after>这些标签里面的值都解析出来,并生成对应的beandefinition,相互之间配置好的。然后注册如容器。
第二个步骤:
如下面ioc的最后一步,applybeanpostprocessorsafterinitialization(),在每个bean初始化之后,如果需要,就调用AspectJAwareAdvisorAutoProxyCreator中的postProcessBeforeInitialization为Bean生成代理。
我们首先判断哪些对象需要生成代理,对需要的bean进行生成代理操作。然后为指定的class寻找合适的advisor。这里有两个条件,都是与pointcut的expression相关,首先判断该类是不是match,然后判断该类里面的哪些方法match,然后把这些满足条件的方法拿出来。然后就是选择proxyfactory,是使用jdk还是cglib,最后就是使用相应的getproxy方法,进行代理对象的产生过程。jdk,我们很熟悉就是使用newproxyinstance()方法,我们还要把之前满足条件的advice也放进去。这样我们就生成了我们需要的对象的代理对象。
我们在使用代理对象的时候,比如使用一个方法,会触发invoke()方法。invoke中,我们有一个之前代理生成过程中配置的拦截链,然后就是使用拦截链中的方法进行递归调用(proceed方法)。
![微信图片_20180602112503.jpg](https://img.haomeiwen.com/i4468918/f7aa738c7f5277a4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
网友评论