Spring基础-上-概念篇

来源:互联网 发布:重装ubuntu系统分区 编辑:程序博客网 时间:2024/06/05 16:20

*什么是IoC(Inversion of Control)?

即控制反转。其思想是控制资源获取的方向。传统的资源获取的方式为向容器发起请求,然后容器返回资源,而应用了IOC之后,容器主动地将资源退送给它所管理的组件,组件要做的仅仅是选择一种合适的方式来接收资源即可。

买菜的例子。

*什么是DI(Dependency Injection)?

即依赖注入。通常来讲,一个复杂的应用需要多个类相互协作,譬如类A要实现功能A需要类B的协作,那么类A就是依赖于类B,传统的做法是在类A的内部直接创建B的对象,然后使用B的功能,而应用依赖注入之后,类A就可以通过某种约定的方式接收类B的注入,可以是通过setter方法啦什么的

简而言之:组件以一种约定好的方式(譬如:属性注入:property(开发中最常用的注入方式),构造器注入:constructor-arg(使用构造器注入的时候,通过指定注入属性的位置以区分重载的构造器))接收来自容器资源的注入

*为什么要使用IoC或者DI?

为了解耦,为了提高组件的复用性

*bean的作用域?

使用bean节点的scope属性来设置

默认作用域是:单例

通常情况下,在IoC容器中创建的bean是单例的,就是说,对于配置的一个bean,IoC容器会为该bean创建一个单例对象,就是说,每次通过getBean获取响应bean,获取的都是同一个bean

可以设置作用域:原型(prototype)

也就是说,配置的bean是一个原型,每次获取此bean都是新创建的

*bean的声明周期?

配置在IoC容器中的bean的声明周期由容器管理

容器对bean声明周期管理的过程如下:

使用构造器或者工厂方法创建bean的实例

设置bean的属性

调用bean的初始化方法(初始化方法在配置bean的时候可以指定,在定义bean的时候可以定义响应的操作)

bean就可以使用了

在容器关闭之前,调用bean的销毁方法(销毁方法的配置和定义和初始化方法相同)(所谓后置处理器,就是在bean被实例化之后再对bean进行操作的处理器)

对bean的生命周期进行更为详细的处理,可以使用bean的后置处理器BeanPostProcessor

显然咯,意思是什么呢?通常情况下呢,我们在bean的声明周期中能参与的部分是:设置属性,设置初始化方法,设置销毁方法,就这么多,但是,有时候呢,在bean被创建之前,需要做一些检验啥的,不能在初始化方法中做呀,因为逻辑不对呀,初始化说明这个对象就要创建啦。就想着能不能在初始化之前做了,OK,需求来了,就有解决方法咯

针对不同的bean可能需要不同的后置处理器,那么怎么处理就要自己写了,OK,Spring提供了一个后置处理器接口叫BeanPostProcessor,你可以编写自己的后置处理器,只要实现了这个接口中的两个方法:初始化之前方法和初始化之后方法。然后在XML中进行配置就好。

其实,之前用到的一个PropertyPlaceholderCongurer也是一个bean后置处理器,只不过是Spring自带的罢了

*Spring使用注解时的自动扫描?

组件扫描(component scanning)能够从classpath下自动扫描、侦测、和实例化具有特定注解的组件。这些注解包括:

@Component 基本注解,标识了一个受Spring管理的组件

@Respository 标识了持久层组件

@Service 表示了服务层(业务层)组件

@Controller 标识了表现层组件

(虽然分了这几种,但是Spring并不知道被注解的类到底是用来干嘛的,所以Spring只知道这些被上述标记标记的类是组件,至于组件干什么呃不知道,所以,这些所谓的标记实际上是可以混用的)

对于扫描到的组件,Spring有自己的默认的命名策略:使用非限定类名,第一个字母小写,也可以通过value属性标识组件的名称,什么意思呢?由于是使用注解,注解的话就不在XML中配置bean了,那被注解的bean在实例化后的id是什么呢,就是前面的规则:首字母小写,其他不变,那如果想自己指定名称呢?使用上述注解的value属性指定即可

*Spring泛型依赖注入?

首先呢,该特性是Spring4之后加入的

Spring4.X中可以为子类注入子类对应的泛型类型的成员变量的引用,好好体味这句话,核心就是:一对接口有依赖关系,而且这两个接口都是泛型类,而且泛型的参数类型相互关联,那对于这两个接口的子类,如果对应的泛型参数类型相同,那么这两个子类会自动产生依赖关系 

*什么是AOP(Aspect Oriented Programming)?

即面向切面编程

首先呢是出于两方面的考虑:

1.有一些通用的功能,譬如日志或者事务,这些是都要做的,但是对于一个特定的业务功能来说,如果要自己负责写日志的话,那代码会臃肿很多,而且代码没有很强的针对性

2.对于一些通用的功能,如果由自己负责来写,用到的地方都要写,上面说的臃肿是一方面,但是另外一方面就是修改起来很麻烦,那把这些通用功能封装到一个类里面再调用,的确可以改善第二点,但是第一点,代码臃肿是不可避免的

所以就有了如何能让业务组件更专注的专注于自己的业务,那些通用功能就神不知鬼不觉的自己做好了呢?那就是使用AOP咯,AOP的核心是动态代理

切面:横切关注点(跨越应用程序多个模块的功能)被模块化之后的特殊对象

通知:切面要完成的工作

目标:被通知的bean

代理:向目标对象应用通知之后的对象

连接点:程序执行的某个位置,能够插入通知的地方,实际就是程序执行的某个位置:譬如某个方法执行前,或者某个方法执行后,抛出异常后等,是在代码中真实存在的地方,连接点是代码本身的东西

切点:AOP通过切点连接到连接点。一个类中有很多连接点,而怎么去应用通知呢?在哪些连接点应用通知呢?切点就是用来描述接入连接点应用通知的位置的,是AOP切入通知对象的点的描述

*Spring的JDBC Template(JDBC 模板)?

为了是JDBC在Spring中更加容易使用,Spring在JDBC的基础上进行了一层持久层的封装,什么意思呢?通常使用JDBC都是直接使用Java定义好的官方API,但是这样做有一个不好的地方就是:会有很多重复的代码,譬如开始一个事务,然后写内容,然后要么提交事务,要么回滚事务,整个代码中,核心代码就是操作数据库的那几句,其余的都是没有什么用的代码,那Spring根据

这个特点,对JDBC进行了封装,建立了一个JDBC的存取框架。

作为Spring JDBC框架的核心,JDBC模板设计的目的就是为了为不同类型的JDBC操作提供模板方法,每个模板都能控制整个过程,将数据库的存取工作降到最低。

*构造器,静态代码快,非静态代码快的执行顺序?

静态代码快早于非静态代码快早于构造器。

其中,静态代码快在类加载的时候就执行了,什么意思呢,就是如果有Main方法,静态代码块是在Main方法执行之前执行的哦

*Spring中的事务管理?

事务管理是企业级开发中必不可少的技术,用来保证数据的完整性和一致性

事务的四个关键属性(ACID):

原子性(Atomic):事务是一个原子操作,事务中的动作要么全部执行,要么全部不执行

一致性(Consist):一旦事务正确执行,那么数据出于一种满足业务需求的一致性状态中

隔离性(Isolated):多个事务可能会同时处理互斥资源,因此要求事务应该与其他事务隔离开来,防止数据损坏嘛

持久性(Durable):一旦事务完成,其产生的效果具有持久性,通常呢,事务产生的影响直接是写入数据库的,就是说,如果事务正确执行,那么数据库就会被修改

使用原生JDBC事务的话,就会有很多的模板代码要写:打开连接,开始事务,开始工作,事务正确完成,提交事务,关闭连接,否则,回滚事务,关闭连接。很显然,这其中只有开始工作这一部分代码是真正有用的,其他的都是模板代码,那问题来了,能不能简单一点呢?OK,使用Spring的声明式事务。

声明式事务是什么鬼?

声明式事务是相对于平常的事务而言的。平常的事务就是上面所提到的事务,叫『硬编码式』事务,意思是有关事务的操作都是在用到事务的地方使用写代码的方式使用的

那声明式事务不是硬编码。Spring的AOP框架支持声明式事务管理。

大多数情况下,声明式事务管理要比硬编码式事务管理更好用

事务的传播属性?

当事务方法被另外一个事务方法调用时,必须指定事务的传播属性。例如:方法可能继续在现有的事务中进行,也可能开启新的事务,并在其中运行

事务的传播属性可由事务的传播属性决定

1 0