说一下对spring的理解?
spring是一个轻量级的IOC和AOP的容器框架
IOC(Inversion of Control)控制反转,就是指容器控制程序对象的关系,控制权由应用代码转移到了外部容器,就是spring来控制对象的生命周期和对象之间的关系。设计思想其实是依赖倒置原则。
依赖倒置原则
a.高层模块不应该依赖于底层模块,二者都应该依赖于抽象。
b.抽象不应该依赖于细节,细节应该依赖于抽象。
IOC还有另外一个名字,叫依赖注入(Dependency Injection),即组件之间的依赖关系由容器在运行期间决定。依赖注入的思想是通过反射机制实现的,通过反射调用类中的set方法将事先存在HashMap的类属性注入到类中。从以前的调用者创建被调用者的实例进行调用转变成由spring创建被调用者实例然后注入调用者,就是所谓的依赖注入or控制反转。
IOC初始化过程:XML—(读取)—> Resource—(解析)—>BeanDefinition—(注册)—>BeanFactory
IOC优点就是降低了依赖和被依赖组件双方之间的耦合,降低了业务对象之间替换的复杂性,使之能够灵活的管理对象
AOP(Aspect Oriented Programming)
AOP面向切面编程基于IOC,是一种横切的技术,切开对象内部,将那些影响了多个类的公共行为封装到一个可重用模块,将其命名为aspect,将那些与业务无关,却为业务模块共同调用的逻辑或者责任封装起来,便于减少系统的重复代码,降低模块的耦合度,有利于未来的可维护性。
实现方面使用动态代理,利用截取消息的方式,对消息装饰,取代原来逻辑。或者用静态织入,引入特定的方法创建方面,从而使得编译器可以在编译期间织入有关代码。
AOP使用场景:权限检查,缓存,错误处理,延迟加载,日志记录跟踪,性能优化,持久化,资源池,事务管理
属性注入:在Java代码中可以使用@Autowired或@Resource注解方式进行Spring的依赖注入。两者的区别是:@Autowired默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。
如何解决循环注入?
比如说在A类需要设置B类,B类需要设置C类,C类需要设置A类,这时就出现一个死循环,
spring的解决方案是,初始化A类时把A类的初始化Bean放到缓存中,然后set B类,再把B类的初始化Bean放到缓存中,然后set C类,初始化C类需要A类和B类的Bean,这时不需要初始化,只需要从缓存中取出即可.
或者在构造器初始化时 ,把创建中的Bean放入到一个“当前创建Bean池”中,在初始化类的过程中,如果发现Bean类已存在,就抛出一个“BeanCurrentInCreationException”的异常
一些重要的spring模块:
- Spring Core:核心类库,提供IOC
- AOP:面向切面方面的实现
- JDBC(Java Database Connect):Java数据库连接
- ORM(Object Relation Mapping):支持ORM工具
- JMS(Java Message Service):Java消息服务
- Web:web应用程序支持
- Test:JUnit测试
Spring MVC工作原理
DispatcherServlet:前端控制器,接受用户请求
解析到对应的 Handler:(也就是我们平常说的 Controller 控制器)开始由 HandlerAdapter 适配器处理。
HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑。
处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。
DispaterServlet 把返回的 Model 传给 View(视图渲染),把 View 返回给请求者(浏览器)
Spring 框架中用到了哪些设计模式?
- 单例设计模式 : Spring 中的 Bean 默认都是单例的。
- 工厂设计模式 : Spring使用工厂模式通过 BeanFactory、ApplicationContext 创建 bean 对象。
- 代理设计模式 : Spring AOP 功能的实现。
- 模板方法模式 : Spring 中 jdbcTemplate、hibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
- 适配器模式 :Spring AOP 的增强或通知(Advice)使用到了适配器模式、spring MVC 中也是用到了适配器模式适配Controller。
- 包装器设计模式 : 我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。这种模式让我们可以根据客户的需求能够动态切换不同的数据源。
- 观察者模式: Spring 事件驱动模型就是观察者模式很经典的一个应用。