Spring理解

一、依赖注入DI(Dependency Injection)

如果理解了上述“控制反转”的本质,那么要理解“依赖注入”也不是什么难事了。

在“控制反转”中,我们是这么说的:当java程序需要使用某个对象的时候,直接去spring容器里取就好了。这句话是站在java程序的角度说的。那么反过来,站在spring容器的角度来又该怎么说呢?spring容器直接给出java程序需要的对象,那么java程序就可以直接使用这个对象了。那么这个“给出”的动作,就叫做“依赖注入”。即专业的说法是:当java程序需要使用某个对象的时候,spring容器就把这个对象及其依赖关系注入到java程序里供其使用。

spring里的3种注入方式:接口注入、setter注入、构造器注入。

二、面向切面编程AOP(Aspect Oriented Programming)(JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。Spring默认使用JDK自带的方式创建代理,在无法使用JDK自带方式的情况下使用cglib创建代理)

在谈spring中的AOP之前,我们先来看一种设计模式:代理模式。顾名思义,在Java程序里,“代理”就是某个具体实例对象的代表。

举个例子,具体实例对象就是“总裁”,这个“代表”就是“总裁特助”。那么像类似于端茶送水、打扫办公室这样的非核心业务自然是“总裁特助”来做,“总裁”可是要去做那些核心业务的。但是,想要与“总裁”打交道的,那么必须通过“总裁特助”才可以。也就是说,代理是某个具体实例对象的入口与出口。

上面这个例子用专业术语描述,其实就是AOP的思想。将程序中那些重复的、非核心的业务提取出来,独立进行管理。最常见的就是与数据持久层关系紧密的事务、日志、安全、权限认证等方面的处理。这些虽然都不是项目中最核心的部分,但是在具体应用场景中却又必不可少。

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

Aop 的作用在于分离系统中的各种关注点,将核心关注点(与主要业务相关的)和横切关注点(与主要业务关系不大的)分离开来。AOP的核心思想就是将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。

Spring提供了4种实现AOP的方式:
1.经典的基于代理的AOP
2.@AspectJ注解驱动的切面
3.纯POJO切面
4.注入式AspectJ切面

 

 

AOP的使用场景:AOP用来封装横切关注点,具体可以在下面的场景中使用:

Authentication 权限、Caching 缓存、Context passing 内容传递、Error handling 错误处理、Lazy loading懒加载、Debugging调试、logging, tracing, profiling and monitoring日志(记录、跟踪、优化、校准)、Performance optimization性能优化、Persistence持久化、Resource pooling资源池、Synchronization同步、Transactions 事务。
 

三、spring事物

spring支持 编程式事务管理 和 声明式事务 管理两种方式。

        编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理,spring推荐使用TransactionTemplate。

        声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。

 

MyBatis自动参与到spring事务管理中,无需额外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源与DataSourceTransactionManager引用的数据源一致即可,否则事务管理会不起作用。
@Transactional注解

@Transactional属性 

属性    类型    描述
value    String    可选的限定描述符,指定使用的事务管理器
propagation    enum: Propagation    可选的事务传播行为设置
isolation    enum: Isolation    可选的事务隔离级别设置
readOnly    boolean    读写或只读事务,默认读写
timeout    int (in seconds granularity)    事务超时时间设置
rollbackFor    Class对象数组,必须继承自Throwable    导致事务回滚的异常类数组
rollbackForClassName    类名数组,必须继承自Throwable    导致事务回滚的异常类名字数组
noRollbackFor    Class对象数组,必须继承自Throwable    不会导致事务回滚的异常类数组
noRollbackForClassName    类名数组,必须继承自Throwable    不会导致事务回滚的异常类名字数组
用法

       @Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。

         虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

        默认情况下,只有来自外部的方法调用才会被AOP代理捕获,也就是,类内部方法调用本类内部的其他方法并不会引起事务行为,即使被调用方法使用@Transactional注解进行修饰。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值