AOP动态代理
参考文章:点击查看
- 反射机制是指程序在运行期间可以访问、检测和修改其本身状态或行为的一种能力,使用反射我们可以调用任意一个类对象,以及类对象中包含的属性及方法。
JDK Proxy 和 CGLib 的区别主要体现在以下几个方面:
- JDK Proxy 是 Java 语言自带的功能,无需通过加载第三方类实现;
- Java 对 JDK Proxy 提供了稳定的支持,并且会持续的升级和更新 JDK Proxy,例如 Java 8 版本中的 JDK Proxy 性能相比于之前版本提升了很多;
- JDK Proxy 是通过拦截器加反射的方式实现的;
- JDK Proxy 只能代理继承接口的类;
- JDK Proxy 实现和调用起来比较简单;
- CGLib 是第三方提供的工具,基于 ASM 实现的,性能比较高;
- CGLib 无需通过接口来实现,它是通过实现子类的方式来完成调用的
- JDK Proxy 动态代理的实现无需引用第三方类,只需要实现 InvocationHandler 接口,重写 invoke() 方法即可
- 取得代理对象 Proxy.newProxyInstance
- 与静态代理的区别是静态代理是在编译时进行织入或类加载时进行织入。
Spring IOC流程
- 首先对刷新进行准备,包括设置开始时间、设置激活状态、初始化 Context 环境中的占位符,这个动作根据子类的需求由子类来执行,然后验证是否缺失必要的 properties。
- 刷新并获得内部的 Bean Factory。
- 对 BeanFactory 进行准备工作,比如设置类加载器和后置处理器、配置不进行自动装配的类型、注册默认的环境 Bean。
- 为 Context 的子类提供后置处理 BeanFactory 的扩展能力。如果子类想在 Bean 定义加载完成后,开始初始化上下文之前做一些特殊逻辑,可以复写这个方法。
- 执行 Context 中注册的 Bean Factory 后缀处理器。这里有两种后置处理器,一种是可以注册 Bean 的后缀处理器,另一种是针对 BeanFactory 进行处理的后置处理器。执行的顺序是,先按优先级执行可注册 Bean 的处理器,在按优先级执行针对 BeanFactory的处理器。对 Spring Boot 来说,这一步会进行注解 Bean Definition 的解析。由 ConfigurationClassPostProcessor 触发、由 ClassPathBeanDefinitionScanner 解析并注册到 BeanFactory。
- 按优先级顺序在 BeanFactory 中注册 Bean的后缀处理器,Bean 后置处理器可以在 Bean 初始化前、后执行处理。
- 初始化消息源,消息源用来支持消息的国际化。
- 初始化应用事件广播器。事件广播器用来向 ApplicationListener 通知各种应用产生的事件,是一个标准的观察者模式。
-是留给子类的扩展步骤,用来让特定的 Context 子类初始化其他的 Bean。 - 把实现了 ApplicationListener 的 Bean 注册到事件广播器,并对广播器中的早期未广播事件进行通知。
- 冻结所有 Bean 描述信息的修改,实例化非延迟加载的单例 Bean。
- 完成上下文的刷新工作,调用 LifecycleProcessor 的 onFresh() 方法以及发布 ContextRefreshedEvent 事件。
- 在 finally 中,执行第十三步,重置公共的缓存,比如 ReflectionUtils 中的缓存、 AnnotationUtils 中的缓存等等;
Spring Bean的生命周期
- Bean实例的创建
- 为Bean实例设置属性
- 调用Bean的初始化方法
- 应用可以通过IOC容器使用Bean
- 当容器关闭时,调用Bean的销毁方法
- 调用 Bean 的构造方法创建 Bean;
- 通过反射调用 setter 方法进行属性的依赖注入;
- 如果实现 BeanNameAware 接口的话,会设置 Bean 的 name;
- 如果实现了 BeanFactoryAware,会把 BeanFactory 设置给 Bean;
- 如果实现了 ApplicationContextAware,会给 Bean 设置 ApplictionContext;
- 如果实现了 BeanPostProcessor 接口,则执行前置处理方法;
- 实现了 InitializingBean 接口的话,执行 afterPropertiesSet 方法;
- 执行自定义的 init 方法;
- 执行 BeanPostProcessor 接口的后置处理方法
Spring扩展接口
扩展接口在对 Spring 进行定制化功能扩展时,可以选择一些扩展点,如下图所示。
- BeanFactoryPostProcessor 是 BeanFactory 后置处理器,支持在 BeanFactory 标准初始化完成后,对 BeanFactory 进行一些额外处理。讲 Context 初始化流程时介绍过,这时所有的 Bean 的描述信息已经加载完毕,但是还没有进行 Bean 初始化。例如前面提到的 PropertyPlaceholderConfigurer,就是在这个扩展点上对 Bean 属性中的占位符进行替换。
- BeanDefinitionRegistryPostProcessor,它扩展自BeanFactoryPostProcessor,在执行 BeanFactoryPostProcessor 的功能前,提供了可以添加 Bean Definition 的能力,允许在初始化一般 Bean 前,注册额外的 Bean。例如可以在这里根据 Bean 的 Scope 创建一个新的代理 Bean。
- BeanPostProcessor,提供了在 Bean 初始化之前和之后插入自定义逻辑的能力。与 BeanFactoryPostProcessor 的区别是处理的对象不同,BeanFactoryPostProcessor 是对 BeanFactory 进行处理,BeanPostProcessor 是对 Bean 进行处理。
SpringBoot注解
@SpringBootApplication 包含了 @ComponentScan、@EnableAutoConfiguration、@SpringBootConfiguration 三个注解,而 @SpringBootConfiguration 注解包含了 @Configuration 注解。也就是 Spring Boot 的自动配置功能。@Conditional 注解就是控制自动配置的生效条件的注解,例如 Bean 或 Class 存在、不存在时进行配置,当满足条件时进行配置等。
Spring Bean的作用域
- Singleton: 单例模式,IOC容器中只会存在一个共享的Bean实例,是Spring的默认模式;
- prototype: 原型模式,每次从IOC容器获取Bean的时候,都会创建一个新的Bean实例;
- request: 每次请求都生成一个实例;
- session: 在一次请求会话中,容器返回该Bean的同一实例,不同的- Session请求不同的实例,实例仅在该Session内有效,请求结束,则实例销毁;
- globalsession: 全局的session中,容器返回该Bean的同一个实例,仅在portlet context 有效
Spring AOP 相关增强器
- @Before 前置增强,相当于BeforeAdvice
- @AfterReturning 后置增强,相当于AfterReturningAdvice
- @Around 环绕增强,相当于MethodInterceptor
- @AfterThrowing 抛出增强,相当于ThrowsAdvice
- @AfterFinal增强,不管抛出异常还是正常退出,都会执行,没有对应的增强接口,一般用于释放资源
- @DeclareParents 引介增强,相当于IntroductionInterceptor
SpringMVC 流程
- 客户端请求到DispatcherServlet
- DispatcherServlet根据请求地址查询映射处理器HandleMapping,获取Handler
- 请求HandlerAdatper执行Handler
- 执行相应的Controller方法,执行完毕返回ModelAndView
- 通过ViewResolver解析视图,返回View
- 渲染视图,将Model数据转换为Response响应
- 将结果返回给客户端
Spring 事务实现方式、事务的传播机制、默认的事务类别·
事务实现方式
- 声明式,在xml文件中通过tx:advice来配置事务
- 注解式,在xml文件中定一个事务管理对象(DataSourceTransactionManager),然后加入tx:annotation-driven/, 这样就可以使用@Transactional注解配置事务
事务的传播机制
一共7种事务传播行为,相关code: AbstractPlatformTransactionManager -> getTransaction - PROPAGATION_REQUIRED:如果当前没有事务,则新建一个事务;如果已经存在一个事务,则加入到这个事务中,这也是默认事务类别
- PROPAGATION_SUPPORTS:支持当前事务。如果当前没有事务,则以非事务方式执行
- PROPAGATION_MANDATORY:使用当前事务。如果当前没有事务,则抛出异常
- PROPAGATION_REQUIRES_NEW:新建事务。如果当前存在事务,则把当前事务挂起
- PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作。如果当前存在事务,则把当前事务挂起
- PROPAGATION_NEVER:以非事务方式执行。如果当前存在事务,则抛出异常
- PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则执行与- - PROPAGATION_REQUIRED类似的操作
Spring 提供了5种标准的事件:
- 上下文更新事件(ContextRefreshedEvent):该事件会在ApplicationContext被初始化或者更新时发布。也可以在ConfigurableApplicationContext 接口中的refresh()方法时触发
- 上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始或重新开始容器时触发该事件
- 上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件
- 上下文关闭事件(ContextCloseEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁
- 请求处理事件(RequestHandledEvent):在Web应用中,当一个Http请求(Request)结束时触发该事件
- 自定义事件继承ApplicationEvent, 在通过ApplicationContext 接口的publishEvent()方法发布事件