Spring 问题总结
SpringMvc 优化
¶controller 尽量保持单例
controller尽量保持单例,不要使用原型,这样可以减少创建对象和回收对象的开销.也就是说,如果 controller 的类变量和实例变量可以以方法形参声明的尽量以方法的形参声明,不要以类变量和实例变量 声明,这样可以避免线程安全问题.
¶处理 request 的方法中的形参务必加上@RequestParam 注解
这样可以避免 springmvc 使用 asm 框 架读取 class 文件获取方法参数名的过程.即便 springmvc 对读取出的方法参数名进行了缓存,如果不要读 取 class 文件当然是更加好
¶url 的缓存
阅读源码的过程中,发现 springmvc 并没有对处理 url 的方法进行缓存,也就是说每次都要根据请求 url 去匹配 controller 中的方法 url,如果把 url 和 method 的关系缓存起来,会不会带来性能上的提升呢?有点恶心的是,负责解析 url 和 method 对应关系的 ServletHandlerMethodResolver 是一个 private 的内部类, 不能直接继承该类增强代码,必须要该代码后重新编译.当然,如果缓存起来,必须要考虑缓存的线程安全问题
struts2 和 spring
- Struts2是类界别的拦截, 一个类对应了request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同事又跟一个url对应,所以说从架构本身上SpinrgMVC就容易实现restful url,而struts2的架构实现起来比较费劲,因为struts2中action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其它方式标识器所属方法了。
- SpringMVC的方法之间基本上是独立的,独享request response数据,请求数据通过参数获取,处理结果通过ModelMap交会回给框架,方法之间不共享变量,而struts2高的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码、读程序带来麻烦,每次来了请求就创建一个Action,一个Action对象对应一个request上线文。
- 由于struts2需要针对每个request进行封装,把request、session等servlet声明周期的变量封装成一个一个Map,提供给每个Action使用,并保证线程安全,所以在原则上,是比较耗费内存的。
- 拦截器实现机制上,struts2有以自己的interceptor机制,springmvc用的是独立的AOP方式,这样导致Struts2的配置文件还是比springmvc大。
- springmvc的入口是servlet,而struts2是filter(filter和servlet是不同的,以前认为filter是servlet的一种特殊),这就导致了二者的机制不同,这里就涉及到servlet和filter的区别了。
- springmvc继承了ajax,使用非常方便,只需要@ResponseBody、@RestController就可以实现,而struts2拦截器继承了ajax,在action中处理时必须安装插件或自己写代码继承进去,使用起来也相对不方便。
- springmvc 验证支持JSR303, 处理起来相对更加灵活方便,而struts2验证比较繁琐,感觉太烦乱。
- springmvc和spring是无缝的,从这个项目的管理和安全上也比struts2高(struts2也可以通过不同的目录结构和相关配置做到和springmvc一样的效果,但是需要xml配置的地方不少)
- 设计思想上,struts2更加符合OOP的变成思想,springmvc就比较眼镜,在servlet上扩展。
- springmvc开发线路和性能高于struts2。
- springmvc基本上已经是零配置开发了。
spring总结
¶优点
- spring是java开发中的集大成者,自从有了spring,真的就像java的春天来了。
- spring将常用的设计模式运用的淋漓尽致。
- spring是万能胶,主流的java 框架都可以和它集成(因为spring是从java的基本元素bean做文章,打基础的)。
- 自从有了Annotation,spring几乎可以实现零配置编码,降低了业务对象替换的复杂性,属于低侵入,代码污染极低。
- spring已经形成了自身的生态链,如:springBoot, springCloud, springData(对大数据的支持), 主流趋势spring都有支持。
¶缺点
- spring功能越来越强大,对于java基础比较弱的人,要想搞懂其原理是一件比较难的一件事。
- spring本身暂不支持分布式编程,这也是ejb一直存在的原因(分布式只能借助其他框架来实现)
spring知识点总结
¶spring aop动态代理有哪些实现方式
- jdk动态代理
- cglib动态代理
¶springmvc的父子容器
spring 中所有的容器首先都要实现BeanFactory: IOC容器(默认实现)、AOP容器(扩展关系)、mvc容器(扩展关系)
¶spring哪些类,用到了单例
spring BeanFactory读取配置的时候,只要没有声明为原型(配置scope)默认都是单例的
¶spring是如何保证JVM不会回收bean的
spring运行的时候实际上都是普通的java类,包括代理后的类,都要被ClassLoad加载进来,他都会被jvm的GC机制回收
GC回收的条件:
- 引用没有被使用过(引用计数为0),或者可达性分析不可达,会被自动回收
- 手动赋值null,会被自动回收
¶spring如何实现分布式事务
¶单机事务
- 设置数据源(DataSource )
- 配置事务管理器(TransactionManager),提供提交数据、回滚数据等等的能力
¶分布式事务
主要原理:通过检测异常信息来判断是否中间某一段出现异常,然后分别回滚每个单事务
例子:
事务一:订单生成,结算
事务二:扣钱:支付宝、微信等等
事务三:将积分信息保存到用户信息中
瞬时一致性
事务管理器只有一个,而数据源却有多个,那怎么办?只要实现动态切换数据源,就可以达到回滚的目的。最终一致性
每一步提交都是一部的,然后把操作的内容写到中间件中(MQ、db、日志),一旦发现某一步出错,通过分析数据同样能将数据回滚