码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 工厂模式解耦-单例


    在上一个多例的案例中Class.forName(beanPath).newInstance();

    newInstance(),每次都会调用默认的构造函数创建对象
    对象创建之后长时间不用会被垃圾回收机制回收,下次再用的时候就会调用默认的空构造函数进行重新创建对象,这样就变成了多例(多个对象)
    所以我们创建之后要把对象存储起来。
    先把对象创建出来,并存储到一个map中。
    当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来并存起来。在接下来使用的时候,直接拿过来用就好了。

    bean.properties文件内容

    accountService=com.company.service.impl.AccountServiceImpl

    accountDao=com.company.dao.impl.AccountDaoImpl

    Bean工厂类

    1. /**
    2. * Bean对象实例化工厂
    3. * 1.读取配置文件
    4. * 2.获取类的全限定类名,利用反射实例化对象
    5. */
    6. public class BeanFactory {
    7. //定义一个Properties对象
    8. private static Properties props;
    9. //定义一个map用于存储我们要创建的对象,我们把它称之为容器
    10. private static Map beans;
    11. static {
    12. try {
    13. //实例化Properties对象
    14. props=new Properties();
    15. //获取properties文件的流对象
    16. InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
    17. props.load(inputStream);
    18. //实例化容器
    19. beans=new HashMap();
    20. //取出配置文件中的所有key
    21. Enumeration keys = props.keys();
    22. //遍历枚举
    23. while(keys.hasMoreElements()){
    24. //取出每一个key
    25. String key = keys.nextElement().toString();
    26. System.out.println("key:" + key);
    27. //根据key获取value,即类的全限定类名
    28. String beanPath = props.getProperty(key);
    29. //反射创建对象
    30. Object bean = Class.forName(beanPath).newInstance();
    31. //将实例化的对象存入容器中
    32. beans.put(key,bean);
    33. }
    34. } catch (Exception e) {
    35. e.printStackTrace();
    36. }
    37. }
    38. /**
    39. * 单例模式获取对象
    40. */
    41. public static Object getBean(String beanName){
    42. //传入key值从map容器中直接获取对象
    43. return beans.get(beanName);
    44. }
    45. }
    46. 在main函数中写一个for循环的测试方法,每一次循环模拟一个线程访问可以发现改造后的代码变成了单例。

      测试方法:

      1. public class WebClient {
      2. public static void main(String[] args) {
      3. for (int i = 0; i <5 ; i++) {
      4. IAccountService accountService =(IAccountService) BeanFactory.getBean("accountService");
      5. System.out.println(accountService);
      6. //accountService.save();
      7. }
      8. }
      9. }

      测试结果发现获取bean对象是同一个bean

       升级后的代码可以看到spring容器的缩影。spring本质就是一个容器,它替我们把需要实例化的对象都提前准备好了(大致流程是:读取配置文件,实例化对象,存储到容器中)。我们需要的时候直接向spring容器要就可以了。而且spring很强大,当我们需要某个对象的时候,spring可以自动帮我们对象赋值给变量(依赖注入,后面会学到)

      spring默认是单例模式。(容器中只有一个同名对象)

    47. 相关阅读:
      git_05_撤销暂存区的修改
      linux云服务器病毒处理
      19【CallableStatement 接口】
      Spring AOP原理之动态代理
      正弦信号的平均功率和峰值电压计算举例
      【LeetCode】No.55. Jump Game -- Java Version
      Java 面向对象进阶(二)
      格芯斥资80亿欧元,提高德国德累斯顿的产能,并寻求与台积电相当的政府补贴
      核心实验23_GRE over IPsec vpn_ENSP
      单元测试到底是什么?应该怎么做?
    48. 原文地址:https://blog.csdn.net/lee514/article/details/127992125
      • 最新文章
      • 攻防演习之三天拿下官网站群
        数据安全治理学习——前期安全规划和安全管理体系建设
        企业安全 | 企业内一次钓鱼演练准备过程
        内网渗透测试 | 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号