1、控制反转(IOC)与依赖注入(DI)
1.1 Spring IOC 容器简介及其优点:
Spring 框架的核心是Spring容器。容器创建对象,将它们装配在一起,配置它们并管理它们的完整生命周期。Spring 容器使用依赖注入来管理组成应用程序的组件。容器通过读取提供的配置元数据来接收对象进行实例化,配置和组装的指令。该元数据可以通过XML,Java注解或Java代码提供。
Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
优点:
1.IOC 或 依赖注入把应用程序中的代码量降到最低。
2.它使应用程序容易测试,单元测试不再需要单例和 JNDI 查找机制。
3.最小的代价,最小的影响和最小的侵入性(机制)使松散耦合得以实现。
4.IOC 容器支持即时的实例化和延迟加载服务,加载服务时的饿汉式初始化和懒加载。
1.2 依赖注入(DI)
依赖注入,是 IOC 的一个方面,是个通常的概念,它有多种解释。在依赖注入中不用创建对象,而只需要描述如何创建它们。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(IOC 容器)负责把它们组装起来。
1.3 完成依赖注入有多少种方式(不同类型)以及有什么区别
1.构造函数(构造器依赖)注入:通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
2.setter方法注入:容器通过调用无参构造器或无参 static 工厂方法实例化 bean 之后,调用该 bean 的 setter 方法,即实现了基于 setter 的依赖注入。
3.接口注入:在Spring Framework 中,仅使用构造函数和setter 注入。
依赖注入能够降低系统各组件的依赖关系,提倡面向接口编程。
在 两种方式之间选择时最好的解决方案是用构造器参数实现强制依赖,setter 方法实现可选依赖。 Spring Beans
构造函数注入和 setter 注入的区别
构造函数注入 | setter 注入 |
---|---|
没有部分注入 | 有部分注入 |
不会覆盖 setter 属性 | 会覆盖 setter 属性 |
任意修改都会创建一个新实例 | 任意修改不会创建一个新实例 |
适用于设置很多属性 | 适用于设置少量属性 |
1.4 spring 中有多少种 IOC 容器以及有什么区别?
BeanFactory就像一个包含bean集合的工厂类,它会在客户端要求时实例化 bean。
ApplicationContext接口扩展了 BeanFactory 接口,它在 BeanFactory 基础上提供了一些额外的功能。
BeanFactory和ApplicationContext的区别
BeanFactory | ApplicationContext |
懒加载 | 即时加载 |
语法显式提供资源对象 | 自己创建和管理资源对象 |
不支持国际化 | 支持国际化 |
不支持基于依赖的注解 | 支持基于依赖的注解 |
Application contexts 提供一种方法处理文本消息,一个通常的做法是加载文件资源(比如镜像),它们可以向注册为监听器的 bean 发布事件。另外,在容器或容器内的对象上执行的那些不得不由 bean 工厂以程序化方式处理的操作,可以在Application contexts 中以声明的方式处理。Application contexts 实现了MessageSource 接口,该接口的实现以可插拔的方式提供获取本地化消息的方法。
XMLBeanFactory
最常用的就是 org.springframework.beans.factory.xml.XmlBeanFactory ,它根据 XML 文件中的定义加载 beans。该容器从 XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用。
2.4 Spring IoC的实现机制
Spring中的IoC的实现原理就是工厂模式加反射机制。
示例:
interface Fruit {
public abstract void eat();
}
class Apple implements Fruit {
public void eat() {
System.out.println("Apple");
}
}
class Orange implements Fruit {
public void eat() {
System.out.println("Orange");
}
}
class Factory {
public static Fruit getInstance(String className) {
Fruit f = null;
try {
f = (Fruit)Class.forName(className).newInstance();
}
catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
class Client {
public static void main(String[] a) {
Fruit f = Factory.getInstance("io.github.dunwu.spring.Apple");
if(f != null){
f.eat();
}
}
}
2、面向切面编程(AOP)
2.1 AOP简介
AOP(Aspect Oriented Programming,面向切面编程) ,用于发给我们的 Spring 应用做面向切面的开发, 很多支持由 AOP 联盟提供,这样就确保了Spring和其他AOP框架的共通性。这个模块将元数据编程引入 Spring。
AOP与OOP( Object-Oriented Programming, 面向对象编程) 相辅相成, 提供了与OOP不同的抽象软件结构的视角,在OOP 中, 我们以类(class)作为我们的基本单元, 而 AOP 中的基本单元是 Aspect(切面)
是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。
2.2 Aspect切面
aspect 由 pointcount 和 advice 组成, 它既包含了横切逻辑的定义, 也包括了连接点的定义. Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到切面所指定的连接点中. AOP 的工作重心在于如何将增强编织目标对象的连接点上, 这里包含两个工作:
1、如何通过pointcut 和 advice 定位到特定的 joinpoint 上
2、如何在 advice 中编写切面代码.
可以简单地认为, 使用 @Aspect 注解的类就是切面。
AOP 核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组 API 提供横切功能。比如,一个日志模块可以被称作日志的 AOP 切面。根据需求的不同,一个应用程序可以有若干切面。在 Spring AOP 中,切面通过带有 @Aspect 注解的类实现。
2.3 在 Spring AOP 中,关注点和横切点关注的区别
关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。
横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。
基于 XML Schema 方式和基于注解(@AspectJ )方式的切面实现
前者切面由常规类以及基于 XML 的配置实现,后者涉及到的切面声明的风格与带有 java5 标注的普通 java 类一致。
2.4 什么是切点(JoinPoint)
程序运行中的一些时间点, 例如一个方法的执行, 或者是一个异常的处理,在Spring AOP 中, join point 总是方法的执行点。切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。连接点代表一个应用程序的某个位置,在这个位置我们可以插入一个 AOP 切面,它实际上是个应用程序执行 Spring AOP 的位置。
2.5 什么是通知(Advice),有哪些类型的通知?
通知是在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP 框架触发的代码段。特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice。Spring AOP 使用一个 Advice 作为拦截器,在 JoinPoint “周围”维护一系列的拦截器。
Spring 切面可以应用五种类型的通知:
类型 | 描述 | 注解 |
Before | 前置通知,在 joinpoint 方法之前执行 | @Before |
After Returning | 在连接点方法正常执行完成后执行 | @AfterReturning |
After Throwing | 仅在 joinpoint 方法通过抛出异常退出的通知 | @AfterThrowing |
After (finally) | 在连接点方法之后执行,无论方法退出是正常还是异常返回 | @After |
Around | 在连接点之前和之后执行 | @Around |
2.6 什么是目标对象?
被一个或者多个切面所通知的对象。它通常是一个代理对象。也指被通知(advised)对象。
2.7 指出在 spring aop 中 concern 和 cross-cutting concern 的不同之处
concern 是我们想要在应用程序的特定模块中定义的行为。它可以定义为我们想要实现的功能。
cross-cutting concern 是一个适用于整个应用的行为,这会影响整个应用程序。例如,日志记录,安全性和数据传输是应用程序几乎每个模块都需要关注的问题,因此它们是跨领域的问题。
2.8 AOP 有哪些实现方式?
实现 AOP 的技术,主要分为两大类:
静态代理:指使用AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;
编译时编织(特殊编译器实现)
类加载时编织(特殊的类加载器实现)。
动态代理:在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
JDK 动态代理
CGLIB
2.9 Spring AOP and AspectJ AOP 有什么区别?
Spring AOP 基于动态代理方式实现;AspectJ 基于静态代理方式实现。Spring AOP 仅支持方法级别的 PointCut;提供了完全的 AOP 支持,它还支持属性级别的PointCut。
2.10 如何理解 Spring 中的代理?
将Advice 应用于目标对象后创建的对象称为代理。在客户端对象的情况下,目标对象和代理对象是相同的。
Advice + Target Object = Proxy
2.11 编织(Weaving,也叫织入)简介,什么是织入应用的不同点?
编织是将切面(aspect)和到其他应用类型或对象连接或(去)创建一个通知(advice,或被通知对象)的过程。在 Spring AOP 中,编织可以在编译、加载、运行时执行。