Spring Boot源码(五):BeanFactoryPostProcessor和BeanPostProcessor
BeanFactoryPostProcessor是spring BeanFactory加载Bean后调用,
BeanPostProcessor是Bean初始化前后调用。
BeanFactoryPostProcessor
通俗地说:BeanFactoryPostProcessor是胚胎中直接基因改造,BeanPostProcessor是出生后去整容。
上面是refresh()方法的一部分,之前还调用了
prepareBeanFactory(beanFactory);
配置beanFactory
invokeBeanFactoryPostProcessors(beanFactory);
这个方法去执行BeanFactoryPostProcessor下的类。包括自己定义的一些类,mybatis 整合spring就是通过这个。但我们写crud是不用这些东西的,只看一个简单的demo:
新建一个类实现BeanFactoryPostProcessor :
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanFactory.getBeanDefinition("people");
genericBeanDefinition.setBeanClass(User.class); ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addIndexedArgumentValue(0,"abc");
genericBeanDefinition.setConstructorArgumentValues(constructorArgumentValues);
}
}
实现postProcessBeanFactory()方法,在这个方法中拿到people的beanDefinition,这里用子类去接收,因为子类api更丰富,
然后修改他的beanClass为User类(注意User类没有注入Spring 容器):
public class User {
}
运行Test main方法:
public class Test {
public static void main(String[] args) {
//通过注解配置类初始化 spring上下文
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(MyConfig.class);
//还有一种通过xml来初始化 spring上下文,这里就不介绍了。
//ClassPathXmlApplicationContext
System.out.println(annotationConfigApplicationContext.getBean("people"));
}
}
输出结果为:
component.User@4671e53b
所以我们可以通过BeanFactoryPostProcessor修改beanDefinition。
其中还有两个属性简单说下
autowireMode:自动装配模型。可以设置4个值:
/**
* Constant that indicates no externally defined autowiring. Note that
* BeanFactoryAware etc and annotation-driven injection will still be applied.
*/
int AUTOWIRE_NO = ; /**
* Constant that indicates autowiring bean properties by name
* (applying to all bean property setters).
*/
int AUTOWIRE_BY_NAME = ; /**
* Constant that indicates autowiring bean properties by type
* (applying to all bean property setters).
*/
int AUTOWIRE_BY_TYPE = ; /**
* Constant that indicates autowiring the greediest constructor that
* can be satisfied (involves resolving the appropriate constructor).
*/
int AUTOWIRE_CONSTRUCTOR = ;
默认是0,不自动装配。
如果设置为1,2。那么该类下的依赖不需要@Autowired或@Resource注解了
@Component
public class People {
private User user;
}
对people的beanDefinition设置自动装配,则user也可以正常使用,而不会NPE。
constructorArgumentValues:这个参数会决定bean实例化时调用的构造方法,默认是无参构造器。
ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addIndexedArgumentValue(0,"abc");
genericBeanDefinition.setConstructorArgumentValues(constructorArgumentValues);
这里会调用的是一个参数是字符串的构造方法。
BeanPostProcessor
BeanPostProcessor称为后置处理器,spring框架中很多技术实现了此接口。例如自动注入等,spring中使用了5个子类初始化bean。这个以后再说
此方法中:
这里调用的方法就是实例化前和实例化后。
使用示例:
@Component
public class MyBeanPostProcessor implements BeanPostProcessor { @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// TODO Auto-generated method stub
System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
return bean;
} }
Spring Boot源码(五):BeanFactoryPostProcessor和BeanPostProcessor的更多相关文章
- Spring Boot源码(四):Bean装配
为了演示Spring中对象是如何创建并放到spring容器中,这里新建一个maven项目: 其中pom.xm文件中只引入了一个依赖: <dependencies> <dependen ...
- Spring Boot源码分析-启动过程
Spring Boot作为目前最流行的Java开发框架,秉承"约定优于配置"原则,大大简化了Spring MVC繁琐的XML文件配置,基本实现零配置启动项目. 本文基于Spring ...
- # 曹工说Spring Boot源码(10)-- Spring解析xml文件,到底从中得到了什么(context:annotation-config 解析)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- 曹工说Spring Boot源码(15)-- Spring从xml文件里到底得到了什么(context:load-time-weaver 完整解析)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- 曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- 曹工说Spring Boot源码(28)-- Spring的component-scan机制,让你自己来进行简单实现,怎么办
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- 精尽Spring Boot源码分析 - 内嵌Tomcat容器的实现
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- 曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享
写在前面的话&&About me 网上写spring的文章多如牛毛,为什么还要写呢,因为,很简单,那是人家写的:网上都鼓励你不要造轮子,为什么你还要造呢,因为,那不是你造的. 我不是要 ...
- 曹工说Spring Boot源码(6)-- Spring怎么从xml文件里解析bean的
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- 曹工说Spring Boot源码(9)-- Spring解析xml文件,到底从中得到了什么(context命名空间上)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
随机推荐
- STM32系列之新建工程模板(三)
今天,我将记录STM32如何新建一个模板步骤 第一步:首先先新建一个文件夹(英文命名的)——作为工程根目录 第二步;在文件夹中新建一个名为USER的子目录文件 第三步:点击 MDK 的菜单:Proje ...
- python 利用selenium爬取百度文库的word文章
今天学习如何使用selenium库来爬取百度文库里面的收费的word文档 from selenium import webdriver from selenium.webdriver.common.k ...
- python中常见的报错信息
python中常见的报错信息 在运行程序时常会遇到报错提示,报错的信息会提示是哪个方向错的,从而帮助你定位问题: 搜集了一些python最重要的内建异常类名: AttributeError:属性错误, ...
- vagrant相关
无法挂载共享目录,报错如下 Vagrant was unable to mount VirtualBox shared folders. This is usually because the fil ...
- 《Python学习手册 第五版》 -第10章 Python语句简介
前面在开始讲解数据类型的时候,有说过Python的知识结构,在此重温一下 Python知识结构: 程序由模块组成 模块包含语句 语句包含表达式 表达式创建并处理对象 关于知识结构,前面已经说过我自己的 ...
- Go语言实现:【剑指offer】变态跳台阶
该题目来源于牛客网<剑指offer>专题. 一只青蛙一次可以跳上1级台阶,也可以跳上2级--它也可以跳上n级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 找规律: 1阶:1种: 2阶:2 ...
- 接入谷歌广告错误(主要Adsense)
接入谷歌广告 1. 谷歌初始化完会有透明占位,记得隐藏防止下方游戏无法点击 2. 测试的广告域名似乎需要https和www才能播放adsense视频广告 3. 谷歌广告1009错误,广告id或者账号i ...
- 前端工具配置(webpack 4、vue-cli 3)
随着前端项目复杂度的增加,其所依赖的资源也越来越多,从最初的HTML文件,CSS文件,JS文件发展到现在的各种预处理文件,模板文件等等.文件多了,项目大了,项目的维护就变得更加困难了,用户加载页面的速 ...
- 【转载】python_logging模块
原文:https://www.cnblogs.com/liujiacai/p/7804848.html 1 logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志 ...
- axios中qs的使用
首先qs是一个npm仓库所管理的包,可通过npm install qs命令进行安装. 地址: https://www.npmjs.com/package/qs qs.parse().qs.string ...