30 | 热点问题答疑(3):Spring框架中的设计模式
该思维导图由 AI 生成,仅供参考
简单工厂模式
- 深入了解
- 翻译
- 解释
- 总结
Spring框架应用了多种设计模式,包括简单工厂模式、工厂方法模式、单例模式和代理模式。这些设计模式赋予Spring框架更好的灵活性、可维护性和扩展性,对于Web后端工程师提升设计能力和解决实际工作中的问题具有重要意义。在Spring中,简单工厂模式体现为BeanFactory,解决了硬编码耦合的问题;工厂方法模式体现为FactoryBean,提供更高的灵活性和复杂场景的应用;单例模式通过单例注册表的方式实现,使用HashMap保存单实例对象;代理模式在Spring中应用广泛,包括静态代理和动态代理两种方式,动态代理通过Proxy类和InvocationHandler接口实现,可以对类进行方法级别的切面增强,实现AOP。此外,文章还提到了JDK提供实现动态代理的机制以及通过CGLIB来实现的方式。读者还被鼓励思考newProxyInstance方法的实现方式,并与其他同学一起讨论。整体而言,本文深入浅出地介绍了Spring框架中的设计模式应用,对于想要深入了解Spring框架的读者具有很高的参考价值。
《深入拆解 Tomcat & Jetty 》,新⼈⾸单¥68
全部留言(16)
- 最新
- 精选
- 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-2414 - nightmare老师能讲一下spring这么解决循环依耐的吗
作者回复: Spring只解决了单例bean通过setXxx或者@Autowired进行循环依赖:https://blog.csdn.net/qq924862077/article/details/73926268 其他场景可以想办法绕过:https://www.baeldung.com/circular-dependencies-in-spring
2019-07-1910 - 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-1810 - 802.11文中的工厂模式,有一个疑惑,它确实解决了对象的创建问题,但是对象每一个字段的赋值,工厂模式可以解决吗?或者怎么解决呢,谢谢
作者回复: 字段赋初始值一般来说由类的构造函数或者初始化函数完成,但是Spring比较特殊,可以通过反射注入字段值
2019-07-29 - -W.LI-之前硬着头皮看过这个源码,中间有一步weakcache印象深刻。弱引用缓存,先从缓存中取,没取到获取字节码,校验魔术版本号之类的,最后反射实现。反射效率不高也是这个原因导致的,要获取源文件校验准备初始化(轻量级累加载一次)。2019-07-1812
- QQ怪动态代理的思路便是动态生成一个新类,先通过传入的classLoader生成对应Class对象,后通过反射获取构造函数对象并生成代理类实例,jdk动态代理是通过接口实现的,但很多类是没有针对接口设计的,但是我们知道可以通过拼接字节码生成新的类的自由度是十分大的,所以cglib框架就是通过拼接字节码来实现非接口类的代理。2019-07-186
- QQ怪老师这次加餐面试必问题2019-07-184
- 草戊BeanFactory和FactoryBean的代码示例是一样的?2019-07-2913
- 靠人品去赢这个工厂模式,这各其实实例化的出来我觉得还是工厂bean,但是可以通过getObject来获取bean。这里可以看一下Spring的ObjectFactoryCreatingFactoryBean(通过继承AbstractFactoryBean ,然后由AbstractFactoryBean实现BeanFactory的) public Object getObject() throws BeansException { return this.beanFactory.getBean(this.targetBeanName); } 对应类名字传过来即可,若果是动态那工厂模式就大显神威了。2019-11-071
- 桔子谢谢,我学会了动态代理~2019-09-291