Spring

介绍

Spring的核心是IOC容器和AOP支持,通过IOC容器管理各种类,通过AOP增强服务

IOC 控制反转

概述:Inversion of Control

控制指的是:当前对象对内部成员的控制权。

反转指的是:这种控制权不由当前对象管理了,由其他(类,第三方容器)来管理

实现途径:依赖查找,依赖注入

优点

  • 不用自己组装,拿来就用。
  • 享受单例的好处,效率高,不浪费空间。
  • 便于单元测试,方便切换mock组件。
  • 便于进行AOP操作,对于使用者是透明的。
  • 统一配置,便于修改。

DI 依赖注入

Dependency injection

就是传入一个实例给一个对象

AOP 切面编程

将业务逻辑与样板逻辑分开,实现逻辑的组合,实现原理:动态代理

动静态代理

  • 静态代理
    • 就是改代码,用代理模式在代码里面写死
  • 动态代理
    • 使用 java.lang.reflect.Proxy
    • 只能代理接口
    • 使用反射所以性能不太好
package com.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {

    private Object target;// 维护一个目标对象

    public ProxyFactory(Object target) {
        this.target = target;
    }

    // 为目标对象生成代理对象
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("开启事务");

                        // 执行目标对象方法
                        Object returnValue = method.invoke(target, args);

                        System.out.println("提交事务");
                        return null;
                    }
                });
    }
}
  • cglib代理
    • cglib (Code Generation Library )是一个第三方代码生成类库,运行时在内存中动态生成一个子类对象从而实现对目标对象功能的扩展
    • 优点:解决动态代理只能代理实现接口的类的问题,生成实际子类和字节码故性能优于动态代理

循环依赖

A的实例依赖B,B的实例依赖A

解决办法:
  • 惰性加载,需要的时候再加载进行
  • Spring默认解决办法:
    • 创建A但不初始化,创建并初始化B,此时B拥有的是A的未初始化的引用。实例化B后,再回来初始化A
    • 当前创建bean池:创建过程中一直保持在池里面,用于判断是否循环依赖
    • 三级缓存:
      • 三级:进入实例化阶段的单例对象工厂的cache
      • 二级:已创建未初始化
      • 一级:已实例化
    • 创建过程:
      • A创建到一半,将自己置于三级缓存中,发现依赖B。转而创建B,并一级一级找A缓存,创建B完成后回到A的创建过程继续

杂项

AutoWire与Resource

  • autowire:按类型注入,spring提供的注解
  • resource:按名称注入,java自带,也支持输入参数按类型。找不到时层层退化
  • @Qualifier:存在多个同类型bean时,可以使用它来作区分

bean的作用域

  • singleton : bean在每个Spring ioc 容器中只有一个实例。

  • prototype:一个bean的定义可以有多个实例。

  • request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。

  • session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

  • global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

事务传播机制

① PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。

② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。

③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。

④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。

⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

发布于 2020/08/22 浏览