码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【保姆级】lookup-method标签实践与分析


    【Spring源码系列- IOC】

    1

    【Spring源码】0.安装Gradle环境

    2

    【Spring源码】1.下载与编译_pom relocation to an other version number is not f

    3

    【Spring源码】2.试个水先~Debug找到传说中的三级缓存(图解向,堆图预警)

    4

    【Spring源码】3. xml文件如何转换成BeanDefinition(主要涉及prepareRefresh()+ obtainFreshBeanFactory()两个函数,图解向,堆图预警)_spring xml转bean

    5

    【Spring源码】4. 自己搞个标签?~自定义标签保姆级全过程(图解向,堆图预警)

    6

    【Spring源码】5.spring的bean工厂准备工作(prepareBeanFactory(beanFactory)

    7

    【Spring源码】6. Spring扩展自定义属性编辑器保姆级教程

    8

    【Spring源码】7. 如何添加自定义的BeanFactoryPostProcessor

    9

    【Spring源码】8. 捋下invokeBeanFactoryPostProcessors()主要处理流程

    10

    【Spring源码】9. 超级重要的ConfigurationClassPostProcessor

    11

    【Spring源码】10. 递归调用的processConfigurationClass()方法

    12

    【Spring源码】11. 我是注解类不?checkConfigurationClassCandidate()注解类判断方法详解

    13

    【Spring源码】12. 注册bean处理器registerBeanPostProcessors()

    14

    【Spring源码】13. 国际化处理initMessageSource()源码解析

    【补充内容】【保姆级】SpringBoot项目中的i18n国际化

    15

    【Spring源码】14. 消息多播器(观察者模式)

    【补充内容】【保姆级示例向】观察者模式

    16

    【Spring源码】15. Bean的创建过程(1.概述篇)

    17

    【Spring源码】16. Bean的创建过程(2)

    18

    【Spring源码】17.创建Bean这篇认真的@(・●・)@

    【补充内容】

    【保姆级·创建对象】如何通过Supplier创建对象

    【保姆级·创建对象】如何通过factory-method创建对象

    【保姆级·创建对象】如何利用resolveBeforeInstantiation()在预处理阶段返回一个Bean的实例对象

    19

    【Spring源码】18. factory-method创建对象关键函数详解:instantiateUsingFactoryMethod()

    20

    【Spring源码】19. 没合适的构造器?找determineCandidateConstructors()!

    21

    【Spring源码】20. MergedBeanDefinitionPostProcessor修改/合并bean定义

    【补充内容】

    【保姆级】@PostConstruct & @PreDestroy使用示例

    【Spring源码】AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()详解

    【Spring源码】CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()详解

    22

    【Spring源码】21. 初探循环依赖

    【补充内容】

    【保姆级】手把手Debug循环依赖的整体流程

    【实践向】当移除了三级缓存……

    【分析向】没有三级缓存会导致什么?

    【Spring源码】插播一个创建代理对象的wrapIfNecessary()方法

    23

    【Spring源码】22. 属性填充populateBean()详解

    【补充内容】

    【Spring源码】自动注入·名称:autowireByName()详解

    【Spring源码】自动注入·类型:autowireByType()详解

    【Spring源码】属性值的解析与赋值:populateBean().applyPropertyValues()

    【保姆级】超超超简单的自定义注解实现@Autowired同款功能

    24

    【Spring源码】23. 执行初始化逻辑:initializeBean()

    本文目录

    🌰

    文件结构

    ​创建实体类

    创建配置文件

    新建Spring配置文件

    创建测试类

    测试结果

    ​测试分析

    获取一个类的不同实例

    xml配置文件

    测试结果

    ​测试分析


    一句话:这个注解是在单例中引用原型使用的

    详细点说:Spring中默认的对象都是单例的(而且Spring会在一级缓存中保存该对象以便下次直接获取),如果是原型作用域,每次会创建一个新的对象。如果在单例模式的bean下引用一个原型模式的bean,此时就需要引用lookup-method标签来解决此类问题。 个人理解:由于当调用getBean()方法时,Spring会先在容器中查找有没有这个类,或者这个类的子类,通常情况下,Spring在查找的时候,如果没有匹配或者匹配到多个类都会报错,然而我们又想在一个程序中实现如下两个功能:

    • 分别获取这个父类的两个不同的子类的实例

    • 每次获取到的都是同一个类的不同实例

    而lookup-method这个标签就是解决这些问题的

    本文就是这两种情况的栗子🌰,感兴趣的同学可以跟着一步一步操作,绝对保姆级教程(不愧是俺(˶‾᷄ ⁻̫ ‾᷅˵))

    🌰

    获取同一父类的不同子类

    文件结构

    这个示例一共需要新建6个文件

    ​创建实体类

    有4个实体类(一个父类+两个子类+一个操作类)

    Animal.java(父类)

    1. package com.aqin.custom.MethodOverride.lookup;
    2. /**
    3. * @Description
    4. * @Author aqin1012 AQin.
    5. * @Date 2022/8/22 9:28 AM
    6. * @Version 1.0
    7. */
    8. public class Animal {
    9. public Animal() {
    10. System.out.println("吃点啥嘞?");
    11. }
    12. }

    Cat.java

    1. package com.aqin.custom.MethodOverride.lookup;
    2. /**
    3. * @Description
    4. * @Author aqin1012 AQin.
    5. * @Date 2022/8/22 10:01 AM
    6. * @Version 1.0
    7. */
    8. public class Cat extends Animal{
    9. public Cat() {
    10. System.out.println("吃(_ _).。oO……猫粮");
    11. }
    12. }

    Dog.java

    1. package com.aqin.custom.MethodOverride.lookup;
    2. /**
    3. * @Description
    4. * @Author aqin1012 AQin.
    5. * @Date 2022/8/22 9:29 AM
    6. * @Version 1.0
    7. */
    8. public class Dog extends Animal{
    9. public Dog() {
    10. System.out.println("吃(*≧ω≦)……狗粮");
    11. }
    12. }

    AnimalAction.java

    1. package com.aqin.custom.MethodOverride.lookup;
    2. /**
    3. * @Description
    4. * @Author aqin1012 AQin.
    5. * @Date 2022/8/22 10:25 AM
    6. * @Version 1.0
    7. */
    8. public abstract class AnimalAction {
    9. /**
    10. * 获取执行该动作的动物
    11. *
    12. * @return
    13. */
    14. public abstract Animal getAnimal();
    15. }

    创建配置文件

    新建Spring配置文件

    ​添加如下bean定义:

    1. "dog" class="com.aqin.custom.MethodOverride.lookup.Dog">
    2. "cat" class="com.aqin.custom.MethodOverride.lookup.Cat">
    3. "animalAction_A" class="com.aqin.custom.MethodOverride.lookup.AnimalAction">
    4. "getAnimal" bean="dog">
    5. "animalAction_B" class="com.aqin.custom.MethodOverride.lookup.AnimalAction">
    6. "getAnimal" bean="cat">

    创建测试类

    1. package com.aqin.custom.MethodOverride.test;
    2. import com.aqin.custom.MethodOverride.lookup.AnimalAction;
    3. import org.springframework.context.ApplicationContext;
    4. import org.springframework.context.support.ClassPathXmlApplicationContext;
    5. /**
    6. * @Description
    7. * @Author aqin1012 AQin.
    8. * @Date 2022/8/22 10:29 AM
    9. * @Version 1.0
    10. */
    11. public class TestMethodOverride {
    12. public static void main(String[] args) {
    13. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("MethodOverride.xml");
    14. AnimalAction animalActionA = (AnimalAction) applicationContext.getBean("animalAction_A");
    15. animalActionA.getAnimal();
    16. AnimalAction animalActionB = (AnimalAction) applicationContext.getBean("animalAction_B");
    17. animalActionB.getAnimal();
    18. }
    19. }

    测试结果

    ​测试分析

    先在下图位置打个断点

    ​选择debug方式执行

    不断下一步,直到我们在配置类中配置的4个Bean都能在this对象中的singletonObjects中找到的时候,我们来查看使用了lookup-method标签的那两个Bean,可以看到这两个对象都是cglib的代理对象

    ​当调用到getAnimal()方法时,会跳转到CglibSubclassingInstantiationStrategy中的intercept()方法中

    这里的lo是animalAction_A,可以看到lo中的beanName跟xml配置文件中animalAction_A的标签中的bean="dog"是相对应的(animalAction_B类似)

    获取一个类的不同实例

    文件就用上面的结构就可以了,需要修改下测试类和xml配置文件

    测试类做如下修改

    1. public class TestMethodOverride {
    2. public static void main(String[] args) {
    3. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("MethodOverride.xml");
    4. AnimalAction animalActionB = (AnimalAction) applicationContext.getBean("animalAction_B");
    5. animalActionB.getAnimal();
    6. AnimalAction animalActionB_2 = (AnimalAction) applicationContext.getBean("animalAction_B");
    7. animalActionB_2.getAnimal();
    8. }
    9. }

    xml配置文件

    1. <bean id="dog" class="com.aqin.custom.MethodOverride.lookup.Dog" scope="prototype">bean>
    2. <bean id="cat" class="com.aqin.custom.MethodOverride.lookup.Cat" scope="prototype">bean>

    测试结果

    ​测试分析

    此时this对象中的singletonObjects中就只有animalAction_A和animalAction_B两个了(因为Cat和Dog都的scope设置成了prototype(原型))

    ​可以看到,两次获取的Cat一个是Cat@1730,一个是Cat@1790,并不是同一个对象,实现了在单例中引用原型(单例的bean会被Spring放在一级缓存中保存,以便下次直接获取,所以每次获取到的都是同一个实例)

    返回的实际上是一个动态代理生成的对象

    撒花(。・ω・。)ノ🎉🎉🎉

  • 相关阅读:
    MySQL数据库
    线性表-顺序表学习笔记(基础)
    Ubuntu 22.04 Docker安装笔记
    场景题:海量数据如何判重?
    JSP response对象简介说明
    Max Sum Plus Plus HDU - 1024
    网络-SSE
    前后端结合解决Excel海量公式计算的性能问题
    SpringBoot启动失败报错,spring.profiles.active:@env@中环境变量@无法识别报错_active: @env@
    学点Selenium玩点新鲜~新的一年,让分布式测试有更多玩法
  • 原文地址:https://blog.csdn.net/aqin1012/article/details/127472455
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号