spring简介
1.分层(dao、service、controller)
2.全栈
3.轻量级:跑起来只需要一个jar包,一个容器环境就能跑起来
4.IOC和AOP为内核
5.整合第三方优秀的框架
spring优势:
1.方便解耦,简化开发
2.aop编程的开发,让所有方法前或者后执行一段逻辑
3.声明式事务 @Transactional底层通过aop来实现的
4.方便程序的测试
5.方便集成各种优秀框架
6.降低javaEE API的使用难度
7.源码是经典的java学习范畴 灵活运用思想和设计模式,增强代码设计的思维
spring核心结构
1.core Container ,core,context,spel
2.AOP ,Aspects
3.Data Access , JDBC, JMS
4.Web springmvc,websocket
5.Text
核心思想
第一节IOC
IOC和AOP不是spring提出的,在spring之前就已经存在,只不过更偏向理论化,spring在技术层把这2个思想做了非常好的实现(Java)
1.1什么是IOC?
IOC inversion of control(控制反转),它是一个技术思想,不是技术实现
描述的事情:java开发领域对象的创建,管理的问题。
传统开发方式:比如类A依赖于类B,往往会类A中new一个B的对象
IOC思想下开发方式:我们不用自己去new对象了,而是IOC容器(spring框架)去帮助我们实例化对象并且管理它,我们需要使用哪个对象,去向IOC容器要即可。我们丧失了一个权力(创建、管理对象),
得到了一个福利(不用考虑对象的创建,管理等事情)。
为什么叫做控制反转?
控制:指的是对象创建(实例化、管理)的权力
反转:控制器交给了外部环境(spring框架、IOC容器)
1.2IOC解决了什么问题?
IOC解决对象之间的耦合问题,面向接口,
1.3IOC和DI的区别?
DI:Dependancy Injection(依赖注入)
怎么理解:
IOC和DI描述的是同一件事情(对象实例化及依赖关系维护这件事情),只不过角度不一样
IOC的角度:站在对象的角度,对象实例化及其管理的权力交给了(反转)容器
DI的角度:站在容器的角度,容器会把对象依赖的其它对象注入(送滚去),比如A对象实例化过程中因为声明了一个B类型的属性,那么就需要容器把B对象注入给A
第二节AOP
2.1什么是AOP
AOP:Aspect oriented Programming 面向切面编程/面向方面编程
AOP是OOP的延续,从OOP说起,
OOP三大特征:封装、继承、多态,oop思想是一种垂直纵向的继承体系,
oop编程思想可以解决大多数的代码重复问题,但是有一些情况是处理不了的,比如Animal中多个方法相同位置出现了重复代码,OOP就解决不了
在多个纵向流程中出现的相同子流程代码,我们称之为横切逻辑代码,
横切逻辑代码使用场景很有限:一般事务控制、日志、校验权限
横切逻辑存在的问题:横切逻辑代码重复问题,横切逻辑代码和业务代码混杂一起,代码维护不方便。
AOP出场,AOP独辟蹊径提出横向抽取机制,将横向逻辑代码和业务逻辑代码分离
代码拆分容易,那么如何在不改变原有业务逻辑的情况下,悄无声息的把横切逻辑代码应用到原有的业务逻辑中,达到
和原来一样的效果,这个是比较难的。
2.2AOP解决了什么问题?
在不改变原有业务逻辑的情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复
2.3为什么叫做面向切面编程?
切:指的是横切逻辑,原有业务逻辑代码不能动,只能操作横切逻辑代码,所以面向横切逻辑
面:横切逻辑代码往往影响的是多个方法,每个方法都如同一个点,多个点构成面,有一个面的概念在里面
第三节 手写实现IOC和AOP
问题分析
问题1:new关键字将service层的实现类TransferServiceImpl和Dao层的具体实现类JdbcAccountDaoImpl耦合在了一起,当需要切换Dao层实现类
的时候必须的修改service代码,不符合面向接口开发的最优原则。
思考:
(1)new关键字实例化对象,除了new以外还有什么技术可以实例化对象(反射)
Class.forName("全限定类名"),com.lagou.edu.dao.JdbcAccountDaoImpl,可以把全限定类名配置在xml中
(2)使用工厂模式来通过反射技术生产对象,工厂模式是解耦合非常好的一个方式
解决方案:
* 任务一:读取解析xml,通过反射技术实例化对象并且存储待用(map集合)
* 任务二:对外提供获取实例对象的接口(根据id获取)
简单工厂模式(根据类型区分),工厂方法模式(工厂接口,具体工厂实现自己的工厂类)
单例模式:构造函数必须是私有化,static静态。
懒汉式:先判断类型是否为空,为空去实例化,否则不实例化,会存在线程安全问题,需要在静态fanfare加synchronized关键字实现同步
饿汉式(立即加载):类被jvm虚拟机加载的时候就被实例化
问题2:service层没有添加事务控制,出现异常可能导致数据错乱,问题很严重,尤其是在金融银行行业。
问题分析:数据库事务归根结底是Connection的事务,
connection.commit();提交事务
connection.rollback();回滚事务
1).2次update使用两个数据库连接Connection,这样的话肯定不属于一个事务控制了
2).事务控制目前在dao层进行,没有控制在service层
解决方案:
1)让两次update使用同一个connection连接,两次update是属于同一个线程内的执行调用,我们可以给当前线程绑定一个connection,和当前线程有关系的数据库操作都去使用这
个Connection(从当前线程中去拿)
第一次使用连接,发现当前线程没有,从连接池获取一个连接绑定到当前线程中
2)把事务控制添加在service层
把事务控制添加到service方法中
当很多类及其方法都需要控制时,就需要用到动态代理方式
jdk动态代理要求委托对象必须实现接口,cglib动态代理没有要求委托对象必须实现接口。
动态代理可以对委托对象进行增强,代理对象可以对委托对象进行逻辑的增强。