阅读 52

Spring源码深层探究

Spring源码深层探究

谈及Spring源码不得不说Spring中的2个核心类

1.DefaultListableBeanFactory
XmlBeanFactory继承自DefaultListableFactory,DefaultListableFactory是整个加载的核心部分,
是Spring注册及加载Bean的默认实现。
XmlBeanFactory在其基础上,添加了自定义XML读取器,实现个性化的BeanDefinitionReader读取。

2.XmlBeanDefinitionReader
作用:XML配置文件读取。

xml文件的读取步骤:
1.通过继承AbstractBeanDefinitonReader的方法,使用ResourLoader将资源文件路径转化成对应的
Resource文件。
2.将Resource转化成Document文件
3.对Document和其Element进行进一步解析

Bean解析注册

关于配置文件的封装
Spring中借助Java中的Resource接口对配置文件进行封装。
Resouce接口可以对所有资源文件进行统一的处理。

Resource resource=new ClassPathResource("路径");
InputStream inputStream =resource.getInputStream();
复制代码

Spring对bean解析注册的全过程:

  1. 加载XML文件,封装成Resource对象
  2. 调用Reader对象方法读取XML文件内容,并将相关属性放到BeanDefinition实例
  3. 将BeanDefinition对象放到BeanFactory对象

Bean的生命周期

Bean的生命周期主要会经历一下10个步骤:

  1. Bean的建立:由BeanFactory读取Bean定义文件,并生成各个实例。
  2. Setter注入:执行Bean的属性依赖注入。
  3. BeanNameAware的setBeanName()如果Bean类实现了BeanNameAware接口,则执行其setBeanName()方法。
  4. BeanFactoryAware的setBeanFactory()如果Bean类实现BeanFactoryAware接口,则执行其setBeanFactory()方法。
  5. BeanPostProcessors的processBeforeInitialization() Processors加工
    容器中如果有实现BeanPostProcessors接口的实例,则任何Bean在初始化之前都会执行这个实例的processBeforeInitialization()方法。
  6. InitializingBean的afterPropertiesSet()如果Bean类实现了org.springframework.beans.factory.InitializingBean接口,则执行其afterPropertiesSet()方法。
  7. 如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。在Bean定义文件中使用“init-method”属性设定方法名称,这时会执行initMethod()方法,注意,这个方法是不带参数的。
  8. BeanPostProcessors的processAfterInitialization()容器中如果有实现org.springframework.beans.factory.BeanPostProcessors接口的实例,则任何Bean在初始化之前都会执行这个实例的processAfterInitialization()方法。
  9. DisposableBean的destroy()在容器关闭时,如果Bean类实现了org.springframework.beans.factory.DisposableBean接口,则执行它的destroy()方法。
  10. 如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。在容器关闭时,可以在Bean定义文件中使用“destory-method”定义的方法。

BeanFactory的使用

Spring Bean默认都是通过单例模式来创建对象

  • 单例模式:Spring创建Bean的原则是不等bean创建完成就将beanFactory提早放到缓存中,如果其他bean依赖这个bean可以直接使用,这种机制很好地解决了循环依赖的问题。(这里描述的就是spring的三级缓存机制)
  • 多例模式:bean调用setAllowCircularReferences(false)来禁止循环引用

AOP面向切面编程

应用场景:需要多个不具有继承关系的对象引入一个公共行为
使用方法:

  • 在XML配置文件中 加入aop:aspect-autoproxy开启AOP支持
  • AOP使用的注解
@Aspect
public class AnnotationTest {
    //定义切点
    @Pointcut("execution(* *.saying(..))")
    public void sayings(){}
    /**
     * 前置通知(注解中的sayings()方法,其实就是上面定义pointcut切点注解所修饰的方法名,那只是个代理对象,不需要写具体方法,
     * 相当于xml声明切面的id名,如下,相当于id="embark",用于供其他通知类型引用)
     * <aop:config>
        <aop:aspect ref="mistrel">
            <!-- 定义切点 -->
            <aop:pointcut expression="execution(* *.saying(..))" id="embark"/>
            <!-- 声明前置通知 (在切点方法被执行前调用) -->
            <aop:before method="beforSay" pointcut-ref="embark"/>
            <!-- 声明后置通知 (在切点方法被执行后调用) -->
            <aop:after method="afterSay" pointcut-ref="embark"/>
        </aop:aspect>
       </aop:config>
     */
    @Before("sayings()")
    public void sayHello(){
        System.out.println("注解类型前置通知");
    }
    //后置通知
    @After("sayings()")
    public void sayGoodbey(){
        System.out.println("注解类型后置通知");
    }
    //环绕通知。注意要有ProceedingJoinPoint参数传入。
    @Around("sayings()")
    public void sayAround(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("注解类型环绕通知..环绕前");
        pjp.proceed();//执行方法
        System.out.println("注解类型环绕通知..环绕后");
    }
}
复制代码

在这里插入图片描述

事务

运用场景:存在复杂的事务处理
1.获得连接、关闭连接、事务提交和回滚等操作
2.不需要处理大量的try…catch…finally代码

Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。

常见的有事务有:
1.jdbc事务

 <!--注入 事务管理器  这个注解驱动 告诉 spring 注解驱动 具体上网搜索  -->
   <tx:annotation-driven  transaction-manager="transactionManager"/>
   
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
   </bean>
复制代码

2.Hibernate事务

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
复制代码

3.Java持久化API事务(JPA)

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
复制代码

4.Java原生API事务 (使用以上多种事务)

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManagerName" value="java:/TransactionManager" />
    </bean>
复制代码

关于事务的总结:

  • 服务(Service): service属于业务的具体实现。所以事务本身属于service层。
    在服务层通常要使用@Transactional 进行事务管理
  • @Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public方法将都具有该类型的事务属性(四个事务的特性:原子性、隔离线、持久性、一致性)

SpringMVC

SpringMVC怎么处理请求的 (Handler:处理器 、resolver解析器、Adapter适配器)

  • Model模型:存取数据
  • View视图:展示数据
  • Controller控制器:与用户进行交互

在这里插入图片描述

DispatcherServlet 前端控制器:接收用户请求HandlerAdapter 处理器适配器:选择合适的处理器,并且调用相应功能处理方法 ViewResolver 视图解析器用户发送请求和返回响应的流程:

  1. 发送请求 至DispatcherServlet
  2. 映射处理器 获取处理器映射至 DispatcherServet
  3. HandlerAdapter进行处理器适配
  4. 调用处理器相应功能处理方法
  5. ViewResolver 接收View 进行视图解析
  6. Model加入到View 中进行视图渲染
  7. DispatcherServlet返回响应
文章分类
后端
文章标签