我们从BeanDefination到bean大体上分为这么几步
1.>原生的Bean(就是没有被处理的Bean)
2.>后置处理器的处理
3>调用Init 之类的回调方法
4>填充属性property
也就是说当一个类被实例化之后会经过后置处理器的处理
什么意思呢
>
- 我们UserService 实现了InitializingBean
---------------------->进行了生命周期的回调 和和@PostConstruct作用一样
2.我自己一个类实现了BeanPostProcessor
-------------->构造方法之后干活的
3.构造方法自然老大啊
看清楚现象
construct{构造}—>postProcessBeforeInitialization{后置处理器的Before}–>afterPropertiesSet{
生命周期的回调}—>postProcessAfterInitialization{后置处理器的after}
今天就说下为什么这个顺序 以及这个和aop有什么关系
我们今天来说下registerBeanPostProcessors(beanFactory);这个方法 ,字面上的意思是注册BeanPostProcessors 何为注册就是往工厂中添加BeanPostProcessors
-------------------->我们点进去看吧
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
找出所有实现BeanPostProcessor接口的类 从Bean工厂中
从我们的bdmap中根据类型找出名字
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
//priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// priorityOrderedPostProcessors.remove(2);
//internalPostProcessors: 用于存放Spring内部的BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<>();
//nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
/* 实现PriorityOrdered接口的BeanPostProcessor、
实现Ordered接口的BeanPostProcessor、
普通BeanPostProcessor
* */
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//------------add
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
//priorityOrderedPostProcessors.remove(1);
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
//8.最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
registerBeanPostProcessors(beanFactory, internalPostProcessors);
//重新注册ApplicationListenerDetector(跟8类似,主要是为了移动到处理器链的末尾)
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
他的底层维护了一个集合
this.beanPostProcessors.add(beanPostProcessor);
他总共有7个有3个是从bdmap中获取的
剩下的都是add 的
-----------------------》
我大致说下这几个的作用吧
ApplicationContextAwareProcessor 他的功能是我们一个类如果实现了ApplicationContextAware这个接口,我们可以达到在程序运行中获取applicationContext 继而获取 Bean ,可以动态实现获取bean的信息
BeanPostProcessorChecker 这个的功能是 我们知道所有的实例都要经过后置处理器的处理,如果有一个实例没有经过后置处理器的处理,他就会价差并且打印出信息,
CommonAnnocationBeanPostProcessor----->这个的功能是处理公共注解 比方说生命周期的@PostConstruct
AutowiredAnnotationBeanPostProcessor 的作用是处理@Autowaired注解
RequireAnnocationBeanPostProcessor的作用 解析@Require注解的
ImportAwareBeanPostProcessor 的作用是判断一个类有没有实现ImportAware 这个接口
https://blog.csdn.net/qq_43843037/article/details/103706647
这里有这个接口的说明 redis就是这么配置的
-------------------------------------------------------------------》
我们来测试一个
RequireAnnocationBeanPostProcessor的作用 解析@Require注解的
比方说我们一个类里面有一个name 属性, @Required就是检查有没有给set方法赋值…
我们加了这个注解
启动项目报错 也就是说我们没有给Name属性赋值
------------------------------------>源码在我们手上,我们可以吧这个 RequireAnnocationBeanPostProcessor剔除掉 再测试
此时我们的beanPostProcessors 中就没有RequireAnnocationBeanPostProcessor他了
看我们此时可以打出来 构造 ,此时的@Required 这个注解就不起作用了
因为beanPostProcessors 是一个集合啊 我们直接remove() 就可以吧他剔除
-------------------------------------------------------->
Spring中7个后置处理器 有3个是先前add添加的
有3个从bdmap中得到的
后续又add了2个
-------------------------------------->
我们的aop的原理就是向Spring中添加了一个后置处理器
----------------------------------------------------------------------------------------->我又启了个项目 因为此时源码没有加入aspect的jar
点进来看
从字面上翻译 往容器中注册一个
AspectJAnnotationAutoProxyCreator 如果必要的话
实际上他是给map容器中添加了一个后置处理器
这样我们再从beanDefinationMap中取出来就不是3个了,而是4个了
所以
这个方法的就是给Spring容器中beanProcessors这个容器中加入值
正常来说是7个从bdmap中拿3个 刚开始add2个在,cglib动态代理@Configuration又add1个 然后后面又add了一个
如果加入aspectj的jar 又会加一个 并且这个是加入到bdmap中
==============================>
然后我们看下
看下这个方法 看下Spring的后置处理器如何工作的,换言之
AnnotationAwareAspectJAutoProxyCreator 如何把我们一个原生的Bean给变成代理类的
//------->完成Bean的实例
finishBeanFactoryInitialization
//–>实例化我们单利之前要做得事情
beanFactory.preInstantiateSingletons();
这个方法是把我们所有需要实例化的类拿出来 然后去实例化
------------------------------------------------>现在我们的目的就是来看我们的后置处理器在什么时候工作的 ----------------------》先跑流程 细节明天再说
我们卡一个断点
beanName.equalsIgnoreCase(“OrderDaoImpl”) 因为Spring要实例化的类有10个左右我们的卡成我们的
此时1 >
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
2.>mbd.isSingleton()
然后creatBean
然后我们看啊
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
我们通过这么一个方法返回一个代理对象
现在我们应该继续进入这一个方法看下我们这个动态代理的类什么时候初始化的
------------->换句话说,我们的后置处理器什么时候工作的
///–>1.BeanWrapper instanceWrapper 这个是一个Bean的包装类,何为Bean的包装, 它里面有个getWrappedInstance();方法就能把我们的Bean返回出来,我们真正的对象被这个类给包裹了
//-------------->执行这个代码就相当于执行我们的构造 这个以后再说
instanceWrapper = createBeanInstance(beanName, mbd, args)
我们通过
final Object bean = instanceWrapper.getWrappedInstance();
拿出我们的原生类
;
看此时是原生类,也就是说此时还没有没有被后置处理器处理
----------》
//—>这个方法是我们用来填充属性的明天再说
populateBean(beanName, mbd, instanceWrapper);
//我们通过这个方法来实现我们的代理的 继续缩小范围
exposedObject = initializeBean(beanName, exposedObject, mbd);
//---------》
执行后置处理器的postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//--->执行回调方法
invokeInitMethods(beanName, wrappedBean, mbd);
//执行后置处理器的postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
这下知道吧刚开始的顺序
是构造------->postProcessBeforeInitialization--->invokeInitMethods---->postProcessAfterInitialization
然后现在我们主要的看我们的Aop是在他的postProcessBeforeInitialization 工作的还是在他的postProcessAfterInitialization 里面工作的
看见了没 其实Spring的aop是在他的后置处理器的After 方法工作的
这个方法就是吧后置处理器的getBeanPostProcessors()List拿出来循环执行他的postProcessAfterInitialization 处理Bean
当我们的后置处理器是他的话 我们的Bean就被代理了,
我们点击去 具体去看是如何将我们的bean进行代理的
通过他的父类 AbstractAutoProxyCreator 的postProcessAfterInitialization 这个方法进行的代理
看见了没
wrapIfNecessary(bean, beanName, cacheKey) 通过这个方法 我们返回一个代理对象
现在我们点击进入这个方法 具体看看如何返回我们的代理对象的
1. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
这个方法主要获取关于切面切点的东西 比方说获取切面,切点
此时我们肯定需要代理啊
-------------------->
createProxy() 然后我们点进去看如何进行代理
---------------->
这个方法看他` return proxyFactory.getProxy(getProxyClassLoader());
----------------------------------------》高能 高能
createAopProxy() 我们看这个方法返回AopProxy他
AopProxy是一个接口他的实现类
也就是说如果createAopProxy() 返回的是Jdk代理对象就用Jdk动态代理
如果返回的是cglib就进行cglib代理
我们点击进去看下他用sh
config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)
也就是这三个有一个成立的话我们就进入
否则我们就进行JDK的动态代理
-------------------------------------->很可惜 我现在很菜
只知道config.isProxyTargetClass() 这个怎么配置
我们可以在这个注解进行赋值
@EnableAspectJAutoProxy(proxyTargetClass = )
他默认为false
------------------------------------------------>也就是此时他用的是
JdkDynamicAopProxy
return new JdkDynamicAopProxy(config);
、1. createAopProxy() 返回的对象是JdkDynamicAopProxy
2>点击进去
看见了没
动态代理的标准范式, this代表他实现了InvocationHandler 这个接口
自然讲 invoke就是他的植入逻辑