了解 Spring

0 阅读3分钟

了解 Spring

1、IOC(控制反转)和 AOP(面向切面)

  • IOC (Inversion of Control) 控制反转

    • 原理:将对象的创建权和管理权从“开发者手中”转移到“Spring容器手中”。
    • 好处:解耦。对象不在代码中硬编码 new 出来,而是由容器注入,方便替换和维护。
    • 底层实现:反射 + XML/注解解析 + Map容器(单例池)。
  • AOP (Aspect Oriented Programming) 面向切面

    • 原理:将通用的逻辑(日志、事务、权限)从业务代码中剥离出来,横向切入到业务流程中。
    • 好处:避免代码重复,让业务类专注于业务逻辑。
    • 底层实现动态代理(JDK动态代理基于接口,CGLIB基于继承)。

2、DI(依赖注入)

  • 定义:是 IOC 的具体实现方式。Spring 在创建对象时,自动将对象依赖的属性赋值。
  • 实现方式
    • 字段注入@Autowired 直接加在成员变量上(最常用,但不推荐用于强制依赖)。
    • 构造器注入:加在构造函数上(Spring官方推荐,保证对象创建时属性不为空,不可变对象)。
    • Setter注入:加在Setter方法上(可选依赖)。
  • 底层逻辑:反射 + BeanPostProcessor(后置处理器)。

3、常见注解解释

注解分类作用与解释区别/注意点
@Component分层通用的组件注解,标记为Spring Bean。当不属于Controller/Service/Dao时使用。
@Controller分层标记表现层组件。Spring MVC会识别它为处理器,能接收HTTP请求。
@Service分层标记业务逻辑层组件。语义清晰,目前无特殊技术功能。
@Repository分层标记数据访问层组件。能自动捕获数据库异常并转换为Spring统一异常。
@Mapper分层MyBatis提供的注解,标记数据接口。生成代理实现类,让你只写接口不写实现类就能操作数据库。
@Autowired注入Spring原生注解,自动注入依赖。默认按类型找。如果有多个同类型,需配合@Qualifier按名称找。
@Resource注入JDK标准注解(JSR-250),自动注入依赖。默认按名称找。如果名称找不到,再按类型找。通用性更强。
@PostConstruct生命周期标记初始化方法。构造函数执行后依赖注入完成后执行。用于初始化资源(如加载缓存)。
@TransactionalAOP声明式事务管理。AOP的典型应用。开启事务,方法异常时回滚。注意:类内部调用会导致事务失效(绕过了代理)。

4、单例和多例

特性单例多例
配置@Scope("singleton") 或默认不写@Scope("prototype") 必须显式声明
生命周期容器启动创建,容器销毁消亡。每次获取时创建,Spring只管创建不管销毁。
内存情况全局唯一,所有引用指向同一内存地址。每次获取产生新对象,互不干扰。
线程安全需注意!不要定义可变的成员变量,否则会有线程安全问题。相对安全,每个线程有自己的实例。
性能高(对象复用)。低(频繁创建销毁)。

5、循环依赖

  • 场景:A 依赖 B,B 又依赖 A。

  • Spring 解决方案(三级缓存)

    • Spring 通过提前暴露“半成品”对象(刚创建但还没注入属性的 A)放入缓存,让 B 先拿到 A 的引用,从而打破了循环。
    • 适用范围:仅适用于单例非构造器注入的情况。
  • 延迟注入注解:@Lazy

    • 作用:解决循环依赖(特别是构造器注入导致的循环依赖)。
    • 原理:Spring 不会立即创建真实的依赖对象,而是创建一个代理对象注入进去。
    • 流程
      1. 创建 A 时,发现依赖 B。
      2. 因为 B 标记了 @Lazy,Spring 注入一个 B 的代理对象给 A。
      3. A 创建完成。
      4. 创建 B 时,B 依赖 A,此时 A 已经存在,直接注入。
      5. 真正调用 B 的方法时,代理对象才会去容器中查找真正的 B 实例执行逻辑。