1. BeanFactory和ApplicationContext有什么区别
- BeanFactory是各种bean集合的工厂类,BeanFactory包含了各种bean的定义,以便在接收到客户端请求时将对应的bean实例化。
BeanFactory还包含了bean生命周期的控制。
- ApplicationContext和Bean factory一样具有bean定义、关联根据请求分发bean的功能,但是ApplicationContext在此基础上
- 还提供了其他功能,如支持国际化文本消息、统一资源文件读取方式等。
2. Spring Bean的生命周期
Spring框架的核心特征之一是IOC容器,他管理着应用程序中对象的创建、配置和管理。Spring Bean是被Spring IOC容器管理的对象。
Bean的生命周期是指从Bean的创建到销毁的整个过程。
1. 创建Bean实例
2. 设置Bean属性
- Spring会通过反射设置Bean的属性值,这些属性可以是从其他Bean注入的,或者是在配置文件中指定的值。
- Spring使用@Autowired,@Inject,@Value等注解来自动装配Bean属性。
3. 依赖注入后的处理
- Spring会调用Bean的postProcessBeforeInitialization方法来进一步处理Bean。
- 如果Bean实现了InitializingBean接口,Spring会调用afterPropertiesSet()方法。
- 如果Bean类中带有@PostConstruct注解的方法,Spring也会调用该方法。
- 这些步骤用于执行任何必要的初始化操作。
4. 初始化
- 如果Bean定义中包含了初始化方法(例如init-method属性),Spring也会调用该方法。
5. Bean处于活动状态
6. 销毁Bean
- 当Spring容器关闭时,如果Bean实现了DisposableBean接口,Spring会调用destory方法。
- 如果Bean定义中包含了销毁方法,Spring会调用该方法。
- 如果Bean类中定义了带有@PreDestroy注解的方法,Spring也会调用该方法
3. Spring IOC如何实现
1. 配置元数据:首先需要定义一个配置元数据,这是Spring IOC容器用来创建和配置Bean的基础。
2. 创建容器:Spring提供了两个主要的容器实现。
- BeanFactory:这是一个底层的接口,提供了Bean工厂的基本功能
- ApplicationContext:这是一个更高级的接口
3. 解析配置:当容器启动时,他会解析配置元数据并创建一个内部的数据结构来存储这些信息。
4. Bean实例化:Bean的实例化过程如下
- 根据Bean定义中指定的构造器创建Bean实例。
- 如果Bean定义中指定了依赖,Spring会通过构造器注入、setter注入或者其他注入方式来注入依赖。
- Spring使用BeanPostProcessor接口来允许开发者在Bean实例化前后进行额外的处理。
5. 初始化:Bean实例化后,Spring调用Bean的初始化方法,通常发生在实现了InitializingBean接口的afterPropertiesSet方法
或通过@PostConstruct注解的方法。
6. Bean的使用
7. 销毁
4. Spring AOP实现原理
Spring AOP是一种编程范式,他允许将横切关注点从业务逻辑中分离出来。在Spring框架中,AOP主要通过代理模式来实现。
Spring AOP实现原理如下:
1. 配置切点:定义哪些连结点应该被通知,通常使用切点表达式来指定方法签名。
2. 创建代理:根据目标对象的类型选择适当的代理对象。
JDK动态代理:如果目标对象至少实现了一个接口,则Spring AOP会使用JDK动态代理。
CGLIB动态代理:如果目标对象没有实现接口,Spring AOP会使用CGLIB创建一个子类来代理。
3. 处理方法调用:当客户端代码调用目标对象的方法时,实际上是调用了代理对象。
4. 拦截方法调用:代理对象拦截方法调用,并决定是否需要调用通知。
5. 调用通知:根据配置调用相应的通知。
6. 继续执行:通知完成后,代理对象将调用目标对象的方法。
7. 返回结果:目标方法执行完毕后,代理对象返回结果给客户端代码。
示例:
创建简单的服务类
public class SimpleService {
public void doSomething() {
System.out.println("Doing something...");
}
}
创建切面类
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public