深入拆解Tomcat & Jetty
李号双
eBay技术主管
立即订阅
6067 人已学习
课程目录
已完结 44 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | Java程序员如何快速成长?
免费
模块一 必备基础 (4讲)
01 | Web容器学习路径
02 | HTTP协议必知必会
03 | 你应该知道的Servlet规范和Servlet容器
04 | 实战:纯手工打造和运行一个Servlet
模块二 整体架构 (9讲)
05 | Tomcat系统架构(上): 连接器是如何设计的?
06 | Tomcat系统架构(下):聊聊多层容器的设计
07 | Tomcat如何实现一键式启停?
08 | Tomcat的“高层们”都负责做什么?
09 | 比较:Jetty架构特点之Connector组件
10 | 比较:Jetty架构特点之Handler组件
11 | 总结:从Tomcat和Jetty中提炼组件化设计规范
12 | 实战:优化并提高Tomcat启动速度
13 | 热点问题答疑(1):如何学习源码?
模块三 连接器 (9讲)
14 | NioEndpoint组件:Tomcat如何实现非阻塞I/O?
15 | Nio2Endpoint组件:Tomcat如何实现异步I/O?
16 | AprEndpoint组件:Tomcat APR提高I/O性能的秘密
17 | Executor组件:Tomcat如何扩展Java线程池?
18 | 新特性:Tomcat如何支持WebSocket?
19 | 比较:Jetty的线程策略EatWhatYouKill
20 | 总结:Tomcat和Jetty中的对象池技术
21 | 总结:Tomcat和Jetty的高性能、高并发之道
22 | 热点问题答疑(2):内核如何阻塞与唤醒进程?
模块四 容器 (8讲)
23 | Host容器:Tomcat如何实现热部署和热加载?
24 | Context容器(上):Tomcat如何打破双亲委托机制?
25 | Context容器(中):Tomcat如何隔离Web应用?
26 | Context容器(下):Tomcat如何实现Servlet规范?
27 | 新特性:Tomcat如何支持异步Servlet?
28 | 新特性:Spring Boot如何使用内嵌式的Tomcat和Jetty?
29 | 比较:Jetty如何实现具有上下文信息的责任链?
30 | 热点问题答疑(3):Spring框架中的设计模式
模块五 通用组件 (4讲)
31 | Logger组件:Tomcat的日志框架及实战
32 | Manager组件:Tomcat的Session管理机制解析
33 | Cluster组件:Tomcat的集群通信原理
特别放送 | 如何持续保持对学习的兴趣?
模块六 性能优化 (8讲)
34 | JVM GC原理及调优的基本思路
35 | 如何监控Tomcat的性能?
36 | Tomcat I/O和线程池的并发调优
37 | Tomcat内存溢出的原因分析及调优
38 | Tomcat拒绝连接原因分析及网络优化
39 | Tomcat进程占用CPU过高怎么办?
40 | 谈谈Jetty性能调优的思路
41 | 热点问题答疑(4): Tomcat和Jetty有哪些不同?
结束语 (1讲)
结束语 | 静下心来,品味经典
深入拆解Tomcat & Jetty
登录|注册

30 | 热点问题答疑(3):Spring框架中的设计模式

李号双 2019-07-18
在构思这个专栏的时候,回想当时我是如何研究 Tomcat 和 Jetty 源码的,除了理解它们的实现之外,也从中学到了很多架构和设计的理念,其中很重要的就是对设计模式的运用,让我收获到不少经验。而且这些经验通过自己消化和吸收,是可以把它应用到实际工作中去的。
在专栏的热点问题答疑第三篇,我想跟你分享一些我对设计模式的理解。有关 Tomcat 和 Jetty 所运用的设计模式我在专栏里已经有所介绍,今天想跟你分享一下 Spring 框架里的设计模式。Spring 的核心功能是 IOC 容器以及 AOP 面向切面编程,同样也是很多 Web 后端工程师每天都要打交道的框架,相信你一定可以从中吸收到一些设计方面的精髓,帮助你提升设计能力。

简单工厂模式

我们来考虑这样一个场景:当 A 对象需要调用 B 对象的方法时,我们需要在 A 中 new 一个 B 的实例,我们把这种方式叫作硬编码耦合,它的缺点是一旦需求发生变化,比如需要使用 C 类来代替 B 时,就要改写 A 类的方法。假如应用中有 1000 个类以硬编码的方式耦合了 B,那改起来就费劲了。于是简单工厂模式就登场了,简单工厂模式又叫静态工厂方法,其实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。
Spring 中的 BeanFactory 就是简单工厂模式的体现,BeanFactory 是 Spring IOC 容器中的一个核心接口,它的定义如下:
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入拆解Tomcat & Jetty 》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(13)

  • -W.LI-
    之前硬着头皮看过这个源码,中间有一步weakcache印象深刻。弱引用缓存,先从缓存中取,没取到获取字节码,校验魔术版本号之类的,最后反射实现。反射效率不高也是这个原因导致的,要获取源文件校验准备初始化(轻量级累加载一次)。
    2019-07-18
    7
  • neohope
    //在Proxy类里中:
    //constructorParams的定义如下:
    private static final Class<?>[] constructorParams = { InvocationHandler.class };

    //newProxyInstance无限精简之后就是:
    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
            throws IllegalArgumentException {
        //通过ProxyClassFactory调用ProxyGenerator生成了代理类
        Class<?> cl = getProxyClass0(loader, interfaces);
        //找到参数为InvocationHandler.class的构造函数
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        //创建代理类实例
        return cons.newInstance(new Object[]{h});
    }


    //在ProxyGenerator类中:
    public static byte[] generateProxyClass(final String name,Class<?>[] interfaces, int accessFlags)){}
    private byte[] generateClassFile() {}
    //上面两个方法,做的就是
    //将接口全部进行代理
    //并生成其他需要的方法,比如上面用到的构造函数、toString、equals、hashCode等
    //生成对应的字节码
    //其实这也就说明了,为何JDK的动态代理,必须需要至少一个接口

    作者回复: 👍

    2019-07-24
    5
  • QQ怪
    动态代理的思路便是动态生成一个新类,先通过传入的classLoader生成对应Class对象,后通过反射获取构造函数对象并生成代理类实例,jdk动态代理是通过接口实现的,但很多类是没有针对接口设计的,但是我们知道可以通过拼接字节码生成新的类的自由度是十分大的,所以cglib框架就是通过拼接字节码来实现非接口类的代理。
    2019-07-18
    3
  • nightmare
    老师能讲一下spring这么解决循环依耐的吗

    作者回复: Spring只解决了单例bean通过setXxx或者@Autowired进行循环依赖:https://blog.csdn.net/qq924862077/article/details/73926268

    其他场景可以想办法绕过:https://www.baeldung.com/circular-dependencies-in-spring

    2019-07-19
    2
  • QQ怪
    老师这次加餐面试必问题
    2019-07-18
    2
  • z.l
    老师 ,工厂方法模式没看懂。另外DefaultSingletonBeanRegistry的getBean方法的实现存在线程安全问题吧?虽然用了ConcurrentHashMap,但是if (singletonObject == null) 存在竞态条件, 可能有2个线程同时判断为true,最后产生了2个对象实例。应该用putIfAbsent方法。

    作者回复: 汗颜,代码简化的过程中去掉了线程安全的部分,线程安全的版本应该是这样的:

        //如果没拿到通过反射创建一个对象实例,并添加到HashMap中
        if (singletonObject == null) {
          synchronized(singletonObjects){
        if(singletonObjects.get(beanName) == null){
    singletonObjects.put(beanName,Class.forName(beanName).newInstance());
        }
      }
    }

    2019-07-18
    1
  • 靠人品去赢
    这个工厂模式,这各其实实例化的出来我觉得还是工厂bean,但是可以通过getObject来获取bean。这里可以看一下Spring的ObjectFactoryCreatingFactoryBean(通过继承AbstractFactoryBean ,然后由AbstractFactoryBean实现BeanFactory的)
    public Object getObject() throws BeansException {
    return this.beanFactory.getBean(this.targetBeanName);
    }
    对应类名字传过来即可,若果是动态那工厂模式就大显神威了。
    2019-11-07
  • 桔子
    谢谢,我学会了动态代理~
    2019-09-29
  • 草戊
    BeanFactory和FactoryBean的代码示例是一样的?
    2019-07-29
  • 802.11
    文中的工厂模式,有一个疑惑,它确实解决了对象的创建问题,但是对象每一个字段的赋值,工厂模式可以解决吗?或者怎么解决呢,谢谢

    作者回复: 字段赋初始值一般来说由类的构造函数或者初始化函数完成,但是Spring比较特殊,可以通过反射注入字段值

    2019-07-29
  • nightmare
    如果是基于反射实现的,那增强的业务这么植入的
    2019-07-19
  • 许童童
    工厂方法模式说的就是抽象工厂模式吧
    2019-07-18
    2
  • 阿青,你学到了吗
    基于反射实现的
    2019-07-18
收起评论
13
返回
顶部