Aware感知方法的调用#进入invokeAwareMethod
方法,里面对BeanNameAware
、BeanClassLoaderAware
、BeanFactoryAware
做了检测,并调用了对应的设置方法:
private void invokeAwareMethods(String beanName, Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}
对于BeanFactory,它只支持这些Aware,ApplicationContext会支持更多的Aware 。
Aware感知方法的实战#让Workbench
类实现BeanFactoryAware
接口并打印出创建它的BeanFactory:
@Datapublic class Workbench implements BeanFactoryAware {@Autowiredprivate Person operator;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("BeanFactory => " + beanFactory);}}

文章插图
需要注意的是,一旦你的Bean实现了某个Aware接口,就证明它要感知到某些框架中的东西,这会让它直接与框架产生耦合 。
BeanPostProcessor before初始化的调用#这里和之前的套路一样,并且
before
方法可以返回一个包装过的Bean做为代理(默认不包装,这时wrappedBean==bean) protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {invokeAwareMethods(beanName, bean);// 进行before初始化调用Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}// ...}
遍历每个BeanPostProcessor,调用before初始化方法:@Overridepublic Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessBeforeInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}
没啥好解释的,实际上InstantiationAwareBeanPostProcessor
的过程和它差不多,并且比它复杂 。init-method的调用#
// 调用before初始化Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 调用init-methodinvokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}
那么我们来查看invokeInitMethods
方法:protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {// 该Bean是否是initializingBean的实例boolean isInitializingBean = (bean instanceof InitializingBean);// 如果是,并且有`afterPropertiesSet`方法if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {// 调用afterPropertiesSet方法((InitializingBean) bean).afterPropertiesSet();}if (mbd != null && bean.getClass() != NullBean.class) {// 获取init-method名字String initMethodName = mbd.getInitMethodName();// 如果`initMethodName`不是空并且`initMethodName`并不和`afterPropertiesSet`同名且不是InitalizingBean(防止重复调用),并且Bean中实际有这个方法if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {// 调用initmethodinvokeCustomInitMethod(beanName, bean, mbd);}}}
经验总结扩展阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2023年农历八月初一砍树吉日 2023年9月15日砍树好吗
- 2023年9月15日买宠物好不好 2023年9月15日买宠物好吗
- 2023年9月15日是买狗的黄道吉日吗 2023年9月15日买狗黄道吉日
- 2023年9月15日买猫行吗 2023年9月15日是买猫吉日吗
- 2023年1月28日买牛好吗 2023年1月28日是买牛吉日吗
- 2023年农历八月初一买鸡吉日 2023年9月15日买鸡好不好
- 2023年9月15日是买鸭吉日吗 2023年农历八月初一买鸭吉日
- 2023年农历正月初七买猫吉日 2023年1月28日适合买猫吗
- 2023年农历正月初七宜砍树吗 2023年1月28日砍树吉日一览表
- 2023年1月28日适合塑绘吗 2023年1月28日塑绘黄道吉日