spring IOC&AOP
2020-12-04 01:16:54 0 举报
spring ioc&aop流程分析图,详细分析见csdn-yeleits的博客
作者其他创作
大纲/内容
按scope处理
4. 获取合并的BeanDefinition
getBean(\"mother\")
否
proxy!=null
1. 调用advice的切面行为
属性装配populateBean(...)
其它
① supplier② 工厂方法③ 有methodOverrides,基于cglib实例化④ 无methodOverrides,基于有参或无参构造器
如果有 targetName:① 调用getBean()② 包装成TargetSource
调用ReflectiveMethodInvocation的proceed()方法
pointcut在哪做
(1) beanName形如\"&...\" 且 工厂bean:直接return (2) 普通bean:直接return (3) 普通beanName & 工厂bean ① 在factoryBeanObjectCache中查到:直接return ② 执行FactoryBean的getObject(...) => afterInit的后置处理 => return
singleton
(4)applyPropertyValues(...)通过beanWrapper设置属性
递归调用getBean(...)
ProxyFactoryBean的getObject()
4. singletonsCurrentlyInCreation.remove(beanName)
Y
exposedObject = initializeBean(...)
getBean(name)实例化Bean对象
没有二级缓存
3.2.1 创建beanWrapper
invoke()
return sharedInstance
5. 对依赖的bean,遍历执行:① 注册:2个Map记录依赖关系② 递归调用getBean(...)
N
3.2.2 从wrapper获得原始对象bean
proceed()方法:
1. initializeAdvisorChain()
(1) invokeAwareMethods
依赖当前bean的其它bean是否存在于alreadyCreated??
2.4 getProxy(AopProx):以JDK动态代理或cglib方式创建代理对象
child没有2th缓存
判断是否匹配:根据ClassFilter按类型过滤根据MethodMatcher按方法匹配
2. 是否单例
类型是IntroductionAdvisor
根据 AdvisedSupport构建JdkDynamicAopProxy
3.2.4 通常,单例允许循环引用,执行:if (!this.singletonObjects.containsKey(beanName)) { font color=\"#ff3333\" style=\"font-weight: bold;\
2. 回调方法入口构成行为链
3. singletonObject = singletonFactory.getObject()
执行getInterceptorsAndDynamicInterceptionAdvice()获取拦截链List<Object> chain
getSingleton(...)
exposedObject = 二级缓存
1. 尝试从一级缓存取
3th级缓存记录mother工厂
populateBean(...)
proxy==null
针对bean标签的parent属性
getSingletonInstance()
组装
1.3 放入List<Advisor> advisors
(2) 构建MutablePropertyValues:通过List存放属性名&值
主要逻辑:
isRuntime
(2) 执行beforeInit的BPP处理
是
异常
singletonFactory是匿名内部类功能:生成早期对象引用根据调用getEarlyBeanReference => 调用wrapIfNecessary早期对象可能=原始对象,可能=proxy
return
1.1 遍历 interceptorNames判断每个元素是否形如:prefix + *结尾
遍历advisors:根据advisor类型执行不同逻辑
3.2.3 被合并beanDefinition的BPP处理
bf.getBean(\"mother\")
① 处理byName:a. 遍历未满足的简单属性,递归调用getBean(属性名)b. 放入MutablePropertyValues② 处理byType:a. resolveDependency(...)b. 放入MutablePropertyValues
初始化返回的是否同一个对象exposedObject == bean??
mother实例化
if ( List<Class<?>> interfaces是空的|| 允许直接代理targetClass ) & targetClass不是接口
取出advice进行适配
如何提取:
advice做什么
advisor
2.1 刷新 targetSource
(3) invokeInitMethods① bean实现了InitializingBean接口,执行afterPropertiesSet()方法② java反射执行自定义的init方法
3.1 执行beforeInst、afterInit的BPP处理,生成proxy
newPrototypeInstance():① 拷贝部分配置② 从PrototypePlaceholderAdvisor获取name调用getBean(),放入List<Advisor>③ 其它逻辑类似2.1~2.4
① 从advisor获取advice② 如果advice类型是MethodInterceptor,return元素之一③ 对advice,采用适配器模式处理:按AfterReturningAdvice、MethodBeforeAdvice、ThrowsAdvice,转成不同的MethodInterceptor【invoke(MethodInvocation mi)方法的实现不同】
MethodInvocation方法调用处
2.3 createAopProxy()
return singletonObject
1.1.1 获取bean类型是Advisor、Interceptor的所有beanName,遍历:
1.2 如果是单例,调用getBean()否则,构建PrototypePlaceholderAdvisor
MethodInterceptor拦截器
有二级缓存
return bean
1. 尝试从缓存取
AdvisorAdapter适配器
3.2.5 处理依赖注入populateBean(...)
类型是PointcutAdvisor
通过dependentBeanMapdependenciesForBeanMap记录相互依赖关系的2处
针对bean标签的depend-on属性
3.2.6 exposedObject = initializeBean(...)
3th级缓存记录child工厂
查到
缓存非空
3.2 创建bean实例doCreateBean(...)
2. singletonsCurrentlyInCreation.add(beanName)
二级缓存:放入处
判断是否匹配
1.1.2 如果beanName以prefix开始调用getBean()
执行自定义的GetUpPostProcessor
child实例化
如何获取chain:
将每个intereptor包装成InterceptorAndDynamicMethodMatcher
根据 AdvisedSupport构建ObjenesisCglibAopProxy
3. this.alreadyCreated.add(beanName)
三级缓存:唯一放入处
2.2 如果满足:(允许自动检测接口 & List<Class<?>> interfaces 是空的& 允许直接代理targetClass ):① 根据targetClass解析出所有接口② 设置到List<Class<?>> interfaces
child放入1th缓存清空2th、3th缓存
2. parentBeanFactory!=null &&当前beanFactory中没有相应bd
1.1.3 将所有bean适配后放入List<Advisor> advisors
prototype
getBean(\"child\")
getBean(...)
匿名内部类
mother放入1th缓存清空2th、3th缓存
分情况
(1) 遍历执行afterInst的BPP处理
跳转
chain是空的
通过AdvisorAdapterRegistry从advisor提取Interceptor[]
在校验逻辑中exposedObject从指向mother的原始对象改为指向2th级缓存的代理
十分重要的校验逻辑
(4) 执行afterInit的BPP处理
chain非空
通过计数器遍历执行chain:1. 如果是InterceptorAndDynamicMethodMatcher,带入方法参数计算是否匹配1.1 如果匹配:执行拦截器的invoke方法:执行拦截逻辑后,递归地回调proceed()1.2 如果不匹配:递归执行proceed()2. 如果不是InterceptorAndDynamicMethodMatcher:执行拦截器的invoke方法:执行拦截逻辑后,递归地回调proceed()
(3) 如果有,执行Properties的BPP
① 在一级缓存或二级缓存中查到:直接return② 在三级缓存中查到 => 工厂生产早期对象放入二级缓存,清除三级缓存:return③ 都未查到:return null
适配结果
注:先实例化 (Instantiation)再初始化 (initialization)
一级缓存:放入处
mother从3th级缓存(记录工厂)转入2th级缓存(记录代理)
将可以destroy的bean注册到disposableBeans缓存中
执行createBean(...)
0 条评论
下一页