在使用默认的无参构造方法创建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 实例化相关推荐

  1. 天天用 Spring,bean 实例化原理你懂吗?

    来源:小小木的博客 www.cnblogs.com/wyc1994666/p/10650480.html 本次主要想写spring bean的实例化相关的内容.创建spring bean 实例是spr ...

  2. 异常将上下文初始化事件发送到类的侦听器实例_Spring的Bean实例化原理,这一次彻底搞懂了!...

    前言 之前分析了Spring XML和注解的解析原理,并将其封装为BeanDefinition对象存放到IOC容器中,而这些只是refresh方法中的其中一个步骤--obtainFreshBeanFa ...

  3. 这一次搞懂 Spring 的 Bean 实例化原理

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/l6108003/article/ details/106439525 前言 前两篇文章分析了Spring XML和注解的解析原 ...

  4. Spring源码解析-bean实例化

    Spring源码解析-bean实例化 ​ 本文介绍Spring创建 bean 过程中的第一个步骤:实例化 bean. 1. Bean实例化源码 ​ 虽然实例化Bean有多种方式(包括静态工厂和工厂实例 ...

  5. 05 Bean实例化整体流程

    由于md文档部分hugo插件语法不兼容,建议访问作者网站查阅文章:wlizhi.cc spring源码系列文章,示例代码的中文注释,均是 copy 自 https://gitee.com/wlizhi ...

  6. 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 ...

  7. Spring的Bean实例化、属性注入、对象注入、复杂注入(基于xml配置方式)

    一.Bean实例化的三种方式: (1)使用类的无参构造创建 (2)使用静态工厂创建 (3)使用实例工厂创建 代码实例: (1)项目结构: (2)在pom.xml中导入spring的核心jar包依赖: ...

  8. 实例化Spring Bean:Bean实例化的姿势有多少种?

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  9. Spring源码解析二之创建Bean(实例化)

    上一节我们分析到了createBean,而真正创建Bean的过程在doCreateBean过程,我们可以发现Spring的编码风格,do才是真正的过程,不带do的通常是在做在准备过程,并且我们跳过了一 ...

最新文章

  1. 如何将你在公有云环境中的漏洞找出来?
  2. 对话Nullmax无人车CEO徐雷:造血营收L3,追梦宏图L4
  3. 深度学习利器:TensorFlow在智能终端中的应用——智能边缘计算,云端生成模型给移动端下载,然后用该模型进行预测...
  4. 消息称微软计划收购GitHub,估值超50亿美元
  5. 2020-11-23(“花式扫雷” 辅助制作)
  6. 从索引 0 处开始,初始化字符串的格式不符合规范。
  7. 普中stm32开发板tftlcd显示图片_STM32实例TFTLCD介绍
  8. 如何让智能客服成为企业的生产力工具?
  9. Java字节码指令简介
  10. Windows下Python3.6安装PIL
  11. 再发Wallop和GMail邀请各4个!
  12. 不重启的情况下清除网络共享的密码
  13. linux下安装配置laravel环境,linux下的laravel安装
  14. keras pytorch_使用PyTorch重新创建Keras功能API
  15. asp毕业设计—— 基于asp+access的图书管理系统设计与实现(毕业论文+程序源码)——图书管理系统
  16. Xshell 新手安装教程
  17. Word中查找替换软回车键和回车键
  18. 利用ansys计算机械结构最小安全系数教程,安全系数
  19. nova云主机evacuate简单分析
  20. android多国语言---简写对应国家code

热门文章

  1. Contains Duplicate --包含相同值
  2. HNOI2017 游记
  3. virt-v2v 使用指南
  4. 查看mysql库大小,表大小,索引大小
  5. Query 快速入门教程
  6. C# MongoDB简单增删改查使用
  7. [BootStrap] 富编辑器,基于wysihtml5
  8. 推荐一个MDI模式的远程桌面管理程序
  9. 清北NOIP训练营集训笔记——图论(提高组精英班)
  10. springMVC源码分析