执行Bean 实例化
在使用默认的无参构造方法创建Bean 的实例化对象时,方法getInstantiationStrategy().instantiate()调用了SimpleInstantiationStrategy 类中的实例化Bean 的方法,其源码如下:
//使用初始化策略实例化Bean对象
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {// Don't override the class with CGLIB if no overrides.//如果Bean定义中没有方法覆盖,则就不需要CGLIB父类类的方法if (!bd.hasMethodOverrides()) {Constructor<?> constructorToUse;synchronized (bd.constructorArgumentLock) {//获取对象的构造方法或工厂方法constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;//如果没有构造方法且没有工厂方法if (constructorToUse == null) {//使用JDK的反射机制,判断要实例化的Bean是否是接口final Class<?> clazz = bd.getBeanClass();if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");}try {if (System.getSecurityManager() != null) {//这里是一个匿名内置类,使用反射机制获取Bean的构造方法constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) () -> clazz.getDeclaredConstructor());}else {constructorToUse = clazz.getDeclaredConstructor();}bd.resolvedConstructorOrFactoryMethod = constructorToUse;}catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);}}}//使用BeanUtils实例化,通过反射机制调用”构造方法.newInstance(arg)”来进行实例化return BeanUtils.instantiateClass(constructorToUse);}else {// Must generate CGLIB subclass.//使用CGLIB来实例化对象return instantiateWithMethodInjection(bd, beanName, owner);}
}
通过上面的代码分析,我们看到了如果Bean 有方法被覆盖了,则使用JDK 的反射机制进行实例化,否则,使用CGLib 进行实例化。
instantiateWithMethodInjection() 方法调用SimpleInstantiationStrategy 的子类CGLibSubclassingInstantiationStrategy 使用CGLib 来进行初始化,其源码如下:
//使用CGLIB进行Bean对象实例化
public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {//创建代理子类Class<?> subclass = createEnhancedSubclass(this.beanDefinition);Object instance;if (ctor == null) {instance = BeanUtils.instantiateClass(subclass);}else {try {Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());instance = enhancedSubclassConstructor.newInstance(args);}catch (Exception ex) {throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);}}// SPR-10785: set callbacks directly on the instance instead of in the// enhanced class (via the Enhancer) in order to avoid memory leaks.Factory factory = (Factory) instance;factory.setCallbacks(new Callback[] {NoOp.INSTANCE,new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});return instance;
}private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {//CGLIB中的类Enhancer enhancer = new Enhancer();//将Bean本身作为其基类enhancer.setSuperclass(beanDefinition.getBeanClass());enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);if (this.owner instanceof ConfigurableBeanFactory) {ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));}enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));enhancer.setCallbackTypes(CALLBACK_TYPES);//使用CGLIB的createClass方法生成实例对象return enhancer.createClass();
}
CGLib 是一个常用的字节码生成器的类库,它提供了一系列API 实现Java 字节码的生成和转换功能。我们在学习JDK 的动态代理时都知道,JDK 的动态代理只能针对接口,如果一个类没有实现任何接口,要对其进行动态代理只能使用CGLib。
执行Bean 实例化相关推荐
- 天天用 Spring,bean 实例化原理你懂吗?
来源:小小木的博客 www.cnblogs.com/wyc1994666/p/10650480.html 本次主要想写spring bean的实例化相关的内容.创建spring bean 实例是spr ...
- 异常将上下文初始化事件发送到类的侦听器实例_Spring的Bean实例化原理,这一次彻底搞懂了!...
前言 之前分析了Spring XML和注解的解析原理,并将其封装为BeanDefinition对象存放到IOC容器中,而这些只是refresh方法中的其中一个步骤--obtainFreshBeanFa ...
- 这一次搞懂 Spring 的 Bean 实例化原理
点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/l6108003/article/ details/106439525 前言 前两篇文章分析了Spring XML和注解的解析原 ...
- Spring源码解析-bean实例化
Spring源码解析-bean实例化 本文介绍Spring创建 bean 过程中的第一个步骤:实例化 bean. 1. Bean实例化源码 虽然实例化Bean有多种方式(包括静态工厂和工厂实例 ...
- 05 Bean实例化整体流程
由于md文档部分hugo插件语法不兼容,建议访问作者网站查阅文章:wlizhi.cc spring源码系列文章,示例代码的中文注释,均是 copy 自 https://gitee.com/wlizhi ...
- Spring Bean、XML方式Bean配置、Bean实例化配置、Bean注入
文章目录 Bean管理 一.SpringBoot Bean 初了解 1.1 了解 1.2 Bean的作用域 1.2.1 注意事项 1.3 第三方Bean 二. 基于XML方式Bean的配置 2.1 S ...
- Spring的Bean实例化、属性注入、对象注入、复杂注入(基于xml配置方式)
一.Bean实例化的三种方式: (1)使用类的无参构造创建 (2)使用静态工厂创建 (3)使用实例工厂创建 代码实例: (1)项目结构: (2)在pom.xml中导入spring的核心jar包依赖: ...
- 实例化Spring Bean:Bean实例化的姿势有多少种?
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Spring源码解析二之创建Bean(实例化)
上一节我们分析到了createBean,而真正创建Bean的过程在doCreateBean过程,我们可以发现Spring的编码风格,do才是真正的过程,不带do的通常是在做在准备过程,并且我们跳过了一 ...
最新文章
- 如何将你在公有云环境中的漏洞找出来?
- 对话Nullmax无人车CEO徐雷:造血营收L3,追梦宏图L4
- 深度学习利器:TensorFlow在智能终端中的应用——智能边缘计算,云端生成模型给移动端下载,然后用该模型进行预测...
- 消息称微软计划收购GitHub,估值超50亿美元
- 2020-11-23(“花式扫雷” 辅助制作)
- 从索引 0 处开始,初始化字符串的格式不符合规范。
- 普中stm32开发板tftlcd显示图片_STM32实例TFTLCD介绍
- 如何让智能客服成为企业的生产力工具?
- Java字节码指令简介
- Windows下Python3.6安装PIL
- 再发Wallop和GMail邀请各4个!
- 不重启的情况下清除网络共享的密码
- linux下安装配置laravel环境,linux下的laravel安装
- keras pytorch_使用PyTorch重新创建Keras功能API
- asp毕业设计—— 基于asp+access的图书管理系统设计与实现(毕业论文+程序源码)——图书管理系统
- Xshell 新手安装教程
- Word中查找替换软回车键和回车键
- 利用ansys计算机械结构最小安全系数教程,安全系数
- nova云主机evacuate简单分析
- android多国语言---简写对应国家code