Spring Bean的创建过程:
Spring容器获取Bean和创建Bean都会调用getBean()方法。
getBean()方法
1)getBean()方法内部最终调用doGetBean()方法;
2)transformedBeanName(name); 返回实际的bean名称,删除工厂的取消引用:&;
3)getSingleton(beanName); 从缓存(singletonObjects)中获取,若存在则返回;
4)若缓存中不存在则获取父容器并判断BeanDefinition是否存在于父容器,如果还是找不到则沿着容器的继承体系向父级容器查找;
5)getMergedLocalBeanDefinition(beanName);获取Bean的父子BeanDefinition合并定义,并校验是否为抽象类;
6)确保当前bean依赖的bean的初始化;从Bean中获取依赖的Bean(DependsOn),若存在,则先创建依赖的Bean,创建方式即当前过程getBean();
7)创建singletion实例对象,调用getSingleton()->createBean(),在创建前后会修改各种容器中的值,防止重复创建或冲突等情况;
8)创建prototype实例对象,调用createBean(),在创建前后会修改各种容器中的值,防止重复创建或冲突等情况;
9)创建其他scope(request,session)。创建时会在request中或session中获取,获取不到调用createBean(),在创建前后会修改各种容器中的值,防止重复创建或冲突等情况;
createBean()方法
1)解析bean对应的Class;
2)验证methodOverride对应的方法是否存在?是否有重载?
3)执行InstantiationAwareBeanPostProcessor的applyBeanPostProcessorsBeforeInstantiation尝试生成bean;
4)如果没有生成,则调用 doCreateBean(beanName, bd, args);创建bean
doCreateBean()方法
1)如果BeanDefinition 是单列,取出并清空出缓存
2)实例化:调用createBeanInstance(beanName, mbd, args);
1)解析class,先检查是否有类的访问权限,如果没有权限,抛异常;
2)检查是否有Supplier回调,如果有回调,则执行回调创建实例;
3)检查是否有工厂方法回调,如果有回调,则执行工厂方法回调创建实例;
4)如果都没有回调,则开始自己创建实例。检查缓存是否有解析的构造方法或工厂方法,如果有,再根据缓存选择无参构造(instantiateBean)还是有参构造函数(autowireConstructor)来创建实例;
5)如果缓存没有则执行determineConstructorsFromBeanPostProcessors来解析,最后根据解析结果选择无参构造还是有参构造函数来创建实例;
3)创建后,MergedBeanDefinitionPostProcessor进行合并bean的定义信息后置处理,这个MergedBeanDefinitionPostProcessor包括AutowiredAnnotationBeanPostProcessor等。
4)提前暴露bean,循环依赖处理,并将创建bean实例的ObjectFactory放入工厂缓存(singletonFactories)
5)populateBean属性赋值
1)判断是否有属性需要赋值
2)InstantiationAwareBeanPostProcessors -> postProcessAfterInstantiation 实例化之后的后置处理
3)根据名称或类型,获取需要注入的Bean
4)InstantiationAwareBeanPostProcessor -> postProcessProperties 实例化完成,对属性验证属性
5)筛选属性描述符以进行依赖检查
6)属性赋值
6)赋值后,调用initializeBean方法初始化bean
1)Aware处理,如果实现了Aware接口,会注入属性给这些bean
2)调用BeanPostProcessor -> postProcessBeforeInitialization(bean初始化回调(如InitializingBean 或自定义init-method)之前)
3)调用invokeInitMethods方法,如果实现了InitializingBean 接口,就调用他的afterPropertiesSet方法,如果有自定义方法,就继续调用自定义方法。
4)调用BeanPostProcessor -> postProcessBeforeInitialization(bean初始化回调(如InitializingBean 或自定义init-method)之后)
7)检查早期单例暴露,循环依赖检查,判断是否需要抛出异常
8)根据scope注册bean
至此,Bean创建流程完成!
Spring AOP过程:
@EnableAspectJAutoProxy注解开启 Spring AOP。
@EnableAspectJAutoProxy注解接口内部有@Import(AspectJAutoProxyRegistrar.class);
AspectJAutoProxyRegistrar.class实现ImportBeanDefinitionRegistrar接口,目的将AnnotationAwareAspectJAutoProxyCreator后置处理器的BeanDefinition注入到IOC容器当中。
AnnotationAwareAspectJAutoProxyCreator通过层层继承而实现了BeanPostProcessor接口,所以AnnotationAwareAspectJAutoProxyCreatorBeanPostProcessor。
注册时机:
-
refresh()
-
invokeBeanFactoryPostProcessors(beanFactory);
-
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
-
实现PriorityOrdered的 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)
触发时机:
-
refresh()
-
finishBeanFactoryInitialization(beanFactory);
-
beanFactory.preInstantiateSingletons();
-
getBean(beanName);
-
doGetBean(name, null, null, false);
-
createBean(beanName, mbd, args);
-
doCreateBean(beanName, mbdToUse, args);
-
createBeanInstance(beanName, mbd, args);//创建实例
-
populateBean(beanName, mbd, instanceWrapper);//属性赋值
-
initializeBean(beanName, exposedObject, mbd);//初始化
-
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
-
invokeInitMethods(beanName, wrappedBean, mbd);
-
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
-
-
-
-
-
-
- wrapIfNecessary(bean, beanName, cacheKey); Spring AOP就在这一步进行创建代理并织入增强方法!
-
-
-
代理创建具体流程:
wrapIfNecessary()方法下:
- getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //遍历IOC容器寻找并解析@Aspect注解标注的Bean, 获取匹配当前Bean的 advisor链 (切入点和通知)
- createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));//创建代理类
- proxyFactory.getProxy(getProxyClassLoader());
- createAopProxy().getProxy(classLoader);
- createAopProxy(AdvisedSupport config);//判断是创建JDK代理类还是Cglib代理类,此时会返回ObjenesisCglibAopProxy工厂类或者JdkDynamicAopProxy工厂类
- 判断Optimize:是否使用激进优化策略,仅用于Cglib
- 判断ProxyTargetClass:目标类本身是否是代理类而不是接口
- 判断是否存在代理接口;
如果以上三条都不满足直接使用JDK代理;如果满足其中一条,则再判断Target目标类是否实现了接口或者是否已经实现了jdk代理,如果是则使用JDK代理,不是则使用Cglib代理;
JDK代理的getProx()方法:JDK动态代理机制,当调用代理类的对应方法时,代理类实际上是通过invoke()方法来完成目标类方法的调用,并在里面进行一些代理类想做的其他的操作。
Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);//使用JDK或者Cglib 创建代理实现类
目标方法执行流程:
IOC容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx)
- CglibAopProxy.intercept();拦截目标方法的执行
- 根据ProxyFactory对象获取将要执行的目标方法拦截器链;List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
- 如果没有拦截器链,直接执行目标方法;
- 如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息传入创建一个 CglibMethodInvocation 对象,并调用 Object retVal = mi.proceed();