1 Spring基础

1.1 Spring概述

Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。

  • 控制反转(IoC),是一种设计思想对象的创建转移到由容器来控制,依赖注入(DI)是实现控制反转的一种方法。
  • 面向切面编程(AOP),也是一种设计思想。可以对某个(些)对象的方法增强,即将系统中非核心的业务提取出来形成切面,进行单独处理。比如事务、日志和安全等。实现AOP的技术,主要分为动态代理和静态代理,一般使用动态代理(jdk动态代理或cglib动态代理)。

1.2 SpringIoC

1.2.1 概述

控制反转(IoC),原来开发者使用new的方式创建对象,控制着程序创建所需要的依赖对象,而反转则意为程序中所需要的依赖对象不再由开发者创建,而是程序启动的时候由spring容器创建管理。使用IoC能大大减少程序间的耦合。

1.2.1 实现

Spring一般使用基于XML配置基于注解配置的形式进行开发。
目前都不使用原生的Spring开发,一般使用SpringBoot(基于Spring)并使用注解开发,过程如下。

  • 配置类:使用JavaConfig类实现原来的application.xml配置文件

    1. /*
    2. @Configuration:代表这是一个配置类,用于替代application.xml
    3. 这个类也会被注入到Spring容器中,其本质就是一个@Component
    4. @ComponentScan:默认该类所在的包会被spring扫描注入容器
    5. @EnableAspectJAutoProxy:开启基于注解的AOP模式
    6. */
    7. @Configuration
    8. @ComponentScan
    9. @EnableAspectJAutoProxy
    10. public class SpringConfig {
    11. /**
    12. * 可以在配置类里使用@Bean注入一个bean
    13. */
    14. @Bean("People")
    15. public People getPeople(){
    16. return new People();
    17. }
    18. }
  • 获得IOC容器,同样用getBean方法来获得容器中的对象

    public class SpringTest {
      public static void main(String[] args) {
          ApplicationContext context = 
              new AnnotationConfigApplicationContext(SpringConfig.class);
          Personr person = (Personr)context.getBean("People");
      }
    }
    

1.3 SpringDI

1.3.1 概述

依赖注入(DI),注入将依赖传给调用方,不是像原来的调用方直接使用依赖,注解方式可以注入简单类型数据和对象,复杂类型需要用xml方式注入。

1.3.2 实现

/*
@Component:标明这个类对象会注入到Spring容器。
            衍生出@Respository,@Service,@Controller,
            分别用在Dao层、Service层、Controller层的类上,效果一样。
@Scope("prototype") :注解是告诉Spring该bean的作用域是prototype。
@Value:用在属性上,给属性赋值
@Autowired:用于依赖的自动注入,是通过byType的方式实现;
@Qualifier:必须和@Autowired一起使用,(value = “xxx”)指定一个唯一的bean对象
@Resource: 用于依赖的自动注入,默认通过byName的方式实现,
            如果找不到名字,则通过byType实现。
*/

@Component("person")
@Scope("prototype")
public class Person {
    @Value("张三")
    private String name;

    @Autowired
    @Qualifier(value = "cat")
    private Cat cat;

    @Resource
    private Dog dog;
}

1.4 SpringBean

1.4.1 概述

Bean就是由IoC容器初始化、装配及管理的对象 。

1.4.2 生命周期

扫描类-获取beanDefinnition-实例化-属性填充-回调Aware-
BeanPostProcessor前-初始化-BeanPostProcessor后-销毁

1.4.3 作用域

作用域 描述
singleton 在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,bean作用域范围的默认值。
prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean()。
其他 适用于web的Spring WebApplicationContext环境

1.4.4 自动装配

  • 自动装配是使用spring满足bean依赖的一种方法
  • spring会在应用上下文中为某个bean寻找其依赖的bean。

即@Autowired等注解的功能

1.5 SpringAOP

1.5.1 概述

面向切面编程,指程序在运行期间动态的将某段代码切入到指定方法位置进行的编程方式,底层实现为动态代理。

1.5.2 术语

  • JointPoint(连接点):一般是service层里定义的方法
  • Pointcut(切入点):一般是service层里被增强了的方法
  • Advice(通知):就是要被增强的方法的增强处理,有before,after,afterReturning,afterThrowing,around
  • Aspect(切面):通常是一个类,里面可以定义切入点和通知

    1.5.2 实现

    @Component("beanid")//把这个类放入springioc容器中
    @Aspect//表明当前类是个切面类
    public class AspectAop {
      //切点
      @Pointcut("execution (* com.baozi.sercver..*(..))")
       public void pointcut() {}
    
      @Before("pointcut()")
      public void doBefore() {
          System.out.println("doBefore advice");
      }
    
      @AfterReturning("pointcut()")
      public void doAfterReturning() {
          System.out.println("doAfterReturning advice");
      }
    
      @After("pointcut()")
      public void doAfter() {
          System.out.println("doAfter advice");
      }
    
      @AfterThrowing("pointcut()")
      public void doAfterThrowing() {
          System.out.println("doAfterThrowing advice");
      }
    
      @Around("pointcut()")
      public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
          System.out.println("doAround advice start");
          Object result = pjp.proceed();
          System.out.println("doAround advice end");
          return result;
      }
    }
    

1.6 Spring 事务

Spring 事务分为编程式事务和声明式事务

  • 声明式事务,无侵入业务代码不受污染,但粒度只能作用到方法级别,只能做到对RuntimeException和Error进行事务的自动回滚
  • 编程式事务,侵入在代码中显式调用beginTransaction()、commit()、rollback()等事务管理相关的方法来管理事务,可以作用到代码块级别

1.6.1 声明式事务管理

@EnableTransactionManagement //启注解事务管理,SpringBoot则不需要添加,默认开启
@Transactional //开启事务

1.6.2 编程式事务管理

Spring推荐使用TransactionTemplate。
TransactionTemplate.execute() 方法有一个 TransactionCallback 类型的参数,该接口中定义了一个 doInTransaction() 方法,通常我们以匿名内部类的方式实现 TransactionCallback 接口,并在其 doInTransaction() 方法中书写业务逻辑代码。这里可以使用默认的事务提交和回滚规则,这样在业务代码中就不需要显式调用任何事务管理的 API。

public class XXServiceImpl implements XXService{
    private TransactionTemplate transactionTemplate;
    public void transaferMoney() {
        transactionTemplate.execute(new TransactionCallback() {
            public Object doInTransaction(TransactionStatus status) {                
                return null;
            }            
        });    
    }
}

2 Spring源码

2.1 Spring架构

2.2 Spring
Spring-core
Spring-beans
Spring-context
Spring-aop

启动过程,Bean 的初始化流程,Bean 的生命周期,如何解决循环依赖问题,IoC,AOP

Spring 启动.png
Spring结合了工厂模式和反射实现的IOC

BeanDefinition(Bean的定义),spring根据配置或注解生成

BeanFactory是所有Spring Bean的容器根接口,定义了IOC容器最基本的接口
如getBean(String name): Spring容器中获取对应Bean对象的方法,getType(String name):获取Bean的Class类型

FactoryBean是一种Bean创建的一种方式,对Bean的一种扩展,其本身也是一个bean。实现了这个接口的Bean,初始化创建使用其可封装对象的创建细节。

ApplicationContext是高级容器 AbstractApplicationContext

refresh()方法使用了模板方法,责任链方法模式()

resource资源控制接口

resourceLoader接口 使用的是策略模式

BeanDefinitionReader

BeanDefinitionRegister

image.png

AbstractApplicationContext的refresh()
==================================
postprocessor的种类

  • BeanDefinitionRegisterPostprocessor

容器的后置处理器

  • BeanFactoryPostprocessor
  • BeanPostprocessor

Bean的后置处理器

=================================
spring容器的时间通知机制
事件监听者模式
image.png

image.png
ApplicationEvent代表容器的监听类

image.png

image.png
image.png

=====================================================
依赖注入
image.png
image.png
循环依赖 getsingleton()