Spring(之二)--深入研究

Spring AOP从动态角度考虑程序运行过程,专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,能更好的抽离出各模块关注点。Spring的声明式事务管理正是通过AOP来实现的。

IoC容器允许开发者进行扩展,无需实现BeanFactory和ApplicationContext,而是允许通过两个后处理器对IoC容器进行扩展。

  • Bean后处理器:会对容器中所有Bean进行后处理,对Bean进行额外加强,必须实现BeanPostProcessor接口。
  • 容器后处理器:对IoC容器进行后处理,进行增强容器功能

Bean后处理器

可以无需主动获取Bean后处理器所以无需为其配置id。如果使用ApplicationContext作为Spring容器,它会自动检测容器中的所有Bean,如果发现某个Bean实现了BeanPostProcessor接口,会自动将其注册为Bean后处理器。如果使用BeanFactory作为Spring容器,必须手动注册Bean后处理器,将程序必须获取其然后注册。
下面是Bean后处理器两个方法的回调时机
这里写图片描述

作用:可用于根据容器中的配置的拦截器,创建代理Bean,代理Bean就是对目标Bean进行增强,在目标Bean的基础上进行修改得到新的Bean。

容器后处理器

容器后处理器只负责处理容器本身,必须实现postProcessorBeanFactory接口。这种处理可以对Spring容器进行自定义的扩展。ApplicationContext作为Spring容器,它会自动检测容器中的所有容器后处理器,会自动将其注册为容器后处理器。如果使用BeanFactory作为Spring容器,必须手动调用容器后处理器,将程序必须获取其然后注册。

作用:容器后处理器通常用于对Spring容器进行处理,并且总是在容器实例化任何其他Bean之前,读取配置文件的元数据,并且可能修改这些元数据。容器后处理器的作用域是容器级的,它只对容器本身进行处理,而不对容器中的Bean进行处理;如果需要对容器中的Bean实例进行后处理,则应该考虑使用Bean后处理器。

Spring的“零配置”支持

Spring提供了Annotation来标注Spring Bean

  • @Component 标注普通Spring Bean类
  • @Controller 控制器组件类
  • @Service 业务逻辑组件类
  • @Repository DAO组件类
  • @Scope 指定作用域
  • @Resource 指定协作者Bean,它有个name属性,默认情况下这个值为Bean实例的id。它可以修饰方法也可以修饰实例变量。
  • @PostConstruct
  • @PreDestroy 以上两个都是定制Bean生命周期的
  • @DependsOn 可修饰Bean类或方法
  • @Lazy 用于指定该Bean是否取消预初始化

指定了这些后,让Spring搜索指定路径,此时需要在Spring配置容器中导入context Schema,并指定一个简单的搜索路径。

Spring增强的自动装配和精确装配

@Autowired指定自动装配,可以修饰setter方法、普通方法、实例变量和构造器等。当使用@Autowired标注setter方法时,默认采用byType自动装配策略,如果找到多个会报异常,没找到则什么也不做。@Autowired也可以精确的利用泛型执行自动装配,因此程序只要在基类重定义成员变量,并且配置依赖注入即可,这就是增强配置。@Autowired总是采用byType的自动装配策略。为了实现精确的自动装配。提供了@Qualifier注解可以修饰实例变量,允许根据Bean的id执行自动装配。
@Autowired+@Qualifier的效果等于@Resource

资源访问

Spring为资源访问提供了一个Resource接口,该接口提供了更强的资源访问能力,大量使用Resource来访问底层资源。Resource本身是一个接口,是具体资源访问策略的抽象,也是所有资源访问类所实现的接口。它本身没有提供任何访问底层资源的实现逻辑,针对不同的底层资源,Spring会提供不同的Resource实现类。是典型的策略设计模式。
常见的前缀以及对用的访问策略:

  • classpath:以ClassPathResource实例访问类加载路径下的资源
  • file:以URLAResource方式访问本地文件系统资源
  • http:以URLARes的ource方式访问基于HTTP协议的网络资源
  • 无前缀:由ApplicationContext的实现类来决定访问策略

Spring中的AOP

AOP(Aspect Orient Programming)面向切面编程。AOP要达到的效果是,保证程序员再不修改源代码的前提下,为系统中业务组件的多个业务方法添加通用功能,但AOP的本质是,依然要去修改业务组件的多个业务方法的源代码,只是这个修改是由AOP框架完成,程序员不需要修改!
AOP实现可分为两类:

  • 静态AOP实现:AOP框架在编译阶段对程序进行修改,即实现对目标类的增强,生成静态的AOP代理类。以AspectJ为代表。静态AOP一般有良好的性能,但需要使用特殊的编译器。
  • 动态AOP实现:AOP框架在运行阶段动态生成AOP代理,以实现对目标对象的增强。以Spring AOP为代表。动态AOP实现是纯java实现,无需特殊的编译器,但是性能较差。

AOP的基本概念

AOP框架具有的特征

  • 各步骤之间的良好隔离性
  • 源代码无关性

AOP中的术语:

  • 切面(Aspect):用于组织多个Advice,Advice放在切面中定义
  • 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出。在Spring AOP中总是方法的调用
  • 增强处理(Advice):在特定的切入点执行的增强处理
  • 切入点(PointCut):可以插入增强处理的连接点。就是当某个连接点满足指定要求时,该连接点将被添加增强处理,该连接点也就变成了切入点。
  • 引入:将方法或字段添加到被处理的类中。
  • 目标对象:被进行增强处理的对象。
  • AOP代理:AOP创建的对象,也就是对目标对象的增强
  • 织入:将增强处理添加到目标对象中,并创建一个被增强的对象的过程。
    下面是AOP代理的方法与目标对象的方法
    这里写图片描述

Spring的AOP支持

Spring中的AOP代理由Spring的IoC容器负责生成、管理,所以AOP代理可以直接使用容器中的其他Bean实例作为目标,这种关系可由IoC
容器的依赖注入提供。Spring默认使用Java动态代理创建AOP代理,这样就可以为任何接口实例创建代理了。Spring侧重于AOP实现和Spring IoC容器之间的整合,用于解决企业级开发的常见问题。Spring中的AOP采用基于代理的AOP实现方案。
利用AOP,程序员参与的只有三部分

  • 定义普通的业务组件
  • 定义切入点,一个切入点可能横切多个业务组件
  • 定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作

一旦定义了合适的切入点和增强处理,AOP框架将会自动生成AOP代理。
AOP代理的方法=增强处理+目标对象的方法

Spring有两种选择来定义切入点和增强处理:

  • 基于注解的零配置方式
  • 基于XML配置文件的管理方式

基于注解的零配置方式

  • @Aspect 标注一个java类,作为切面Bean。当使用此标注后,Spring将不会把该Bean当成组件Bean处理,负责自动增强的后处理Bean将会略过该Bean不会对其进行任何增强处理。
  • @Before before增强处理,通常需要指定一个value值,该属性值指定一个切入点表达式。

例如下面形式

@Before("execution(* org.com.tina.app.service.*.*(..))")
public void test(){

}
  • @AfterReturning 将在目标方法正常完成后被织入。指定两个常用属性,pointcut/value用于指定该切入点对应的切入表达式。returning用于指定一个形参名,用于表示Advice方法中定义与此同名的形参,该形参可用于访问目标方法的返回值。
  • @AfterThrowing 主要处理程序中未处理的异常。可指定的属性pointcut/value用于指定该切入点对应的切入表达式。throwing指定一个形参名,用于表示Advice方法中定义与此同名的形参,该形参可用于限制目标方法必须抛出指定类型的异常。
  • @After 与@AfterThrowing的区别:@AfterThrowing增强处理只有在目标方法成功完成才会被织入。@After增强处理不管如何结束都会被织入,这种通常用于释放资源。
  • @Around 它的功能类似于Before和AfterRerurning的总和,它即可在目标方法执行前织入也可在执行后织入。Around可以改变执行目标方法的参数值,也可以改变执行目标方法的返回值。通常在线程安全环境下使用。 如果需要目标方法执行之前和执行之后后向某种状态数据,则应该考虑用Around,尤其是需要改变目标方法返回值时,据只能使用Around了。

定义切入点

定义切入点实质是,为一个切入点表达式起一个名字,从而允许在多个增强处理中从用。
切入点定义包含两部分:

  • 一个切入点表达式
  • 一个包含名字和任意参数的方法签名

如下,定义一个名为test的切入点

@PointCut("execution(* org.com.tina.app.service.*.*(..)")
private void test(){

}

Spring的事务

Spring的事务机制是一种典型的策略模式,PlatformTransactionManager代表事务管理接口,但他不知道底层是如何管理事务,它只要求事务管理需要提供开始事务,提交事务和回滚事务三个方法,但具体实现交给其他实现类来完成,不同的实现类代表不同的事务管理策略。
PlatformTransactionManager是一个与任何事务策略分离的接口,它没有与任何事务性资源捆绑在一起,他可以适应任何的事务策略。策略的切换通常由Spring容器负责管理,应用程序既无需与具体的事务APi耦合,从而将应用和持久化技术、事务API彻底分离。
Spring事务管理的优势是将应用从具体的事务API中分离开,而不是真正提供事务管理的底层实现。
@Transaction 即可用于修饰Spring Bean类,也可以用于修饰Bean类的某个方法,如果修饰Bean类,则表明这些事务设置对整个Bean起作用。如果修饰Bean的某个方法,则表明这些事务设置只对该对象方法有效。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值