Spring框架小结

文章介绍了软件开发的几个核心原则,包括OCP(开闭原则)、DIP(依赖倒置原则)和IoC(控制反转)。OCP强调对扩展开放,对修改关闭,而DIP提倡面向接口编程以降低耦合度。IoC通过Spring框架得以实现,其中依赖注入(DI)是其关键。Spring作为一个轻量级框架,提供了面向切面编程的支持,以及Bean的管理,包括Bean的生命周期和依赖关系。AOP用于处理系统级服务,如日志和事务,以提高代码复用性和维护性。
摘要由CSDN通过智能技术生成

软件开发原则

  1. OCP

    • 什么是OCP?
      • OCP是软件七大开发原则中最基本的一个原则:开闭原则。
        即对扩展开放,对修改关闭。
    • OCP原则是最核心的,最基本的,其他六个原则都是为了这个原则服务的。
    • OCP开闭原则的核心是什么?
      • 只要在拓展系统功能的时候,没有修改以前写好的代码,那么就是符合OCP原则的;
        反之,如果在扩展功能的同时修改了之前的代码,那么这个设计就是失败的,是违背OCP原则的。
    • 当进行系统功能扩展的时候,如果改动了之前稳定的程序,那么整个业务流程都需要重新测试,这不是我们希望看到的结果。
  2. 依赖倒置原则(DIP原则)

    • 面向接口编程,面向抽象编程,不要面向过程。
    • 目的是降低程序的耦合度,提高扩展能力。在这里插入图片描述
  3. 控制反转原则(IoC)

    • 第一,不要在程序中采用硬编码的方式去new对象。(new对象我不管了,new对象的权力我也交出去了)
    • 第二,不要在程序中采用硬编码的方式去维护对象关系了。(对象之间关系的维护我也不管了,也交出去。)
  4. spring框架

    • Spring框架实现了控制反转IoC这种思想
      • spring框架可以帮你new对象,并维护对象与对象之间的关系。
    • Spring是一个实现了IoC思想的容器。
    • 控制反转的实现方式有很多种,其中比较重要的是:依赖注入(DI)。
    • 依赖注入DI,又包含了两种常见方式:
      • 第一种:set注入(执行set方法给属性赋值)
      • 第二种:构造方法注入(执行构造方法给属性赋值)
    • 依赖注入中,依赖是指A对象与B对象的关系,注入是指通过某种手段使A对象和B对象产生关系。
  5. 术语总结

    • OCP:开闭原则(开发原则)
    • DIP:依赖倒置原则(开发原则)
    • IoC:控制反转(一种思想,一种新型的设计模式)
    • DI:依赖注入(控制反转的具体实现方式)

Spring特点

  1. 轻量
    • 从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的处理开销也是微不足道的。
    • Spring是非侵入式的:Spring应用中的对象不依赖于Spring的特定类。
  2. 控制反转
    • Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。
  3. 面向切面
    • Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
  4. 容器
    • Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。
  5. 框架
    • Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。

所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。

Spring对IoC的实现

  1. IoC 控制反转
    • 控制反转是一种思想。
    • 控制反转是为了降低程序耦合度,提高程序扩展力,达到OCP原则,达到DIP原则。
    • 控制反转,反转的是什么?
      • 将对象的创建权利交出去,交给第三方容器负责。
      • 将对象和对象之间关系的维护权交出去,交给第三方容器负责。
    • 控制反转这种思想如何实现呢?
      • DI(Dependency Injection):依赖注入
  2. 依赖注入
    • 依赖注入实现了控制反转的思想。
    • Spring通过依赖注入的方式来完成Bean管理的。
    • Bean管理说的是:Bean对象的创建,以及Bean对象中属性的赋值(或者叫做Bean对象之间关系的维护)。
    • 依赖注入:
      • 依赖指的是对象和对象之间的关联关系。
      • 注入指的是一种数据传递行为,通过注入行为来让对象和对象产生关系。
    • 依赖注入常见的实现方式包括两种:
      • 第一种:set注入
      • 第二种:构造注入
  3. 控制反转实现了

Bean的实例化方式

  • Spring为Bean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活)
    • 第一种:通过构造方法实例化
    • 第二种:通过简单工厂模式实例化
    • 第三种:通过factory-bean实例化
    • 第四种:通过FactoryBean接口实例化

BeanFactory和FactoryBean

  • BeanFactory
    • Spring IoC容器的顶级对象,BeanFactory被翻译为“Bean工厂”,在Spring的IoC容器中,“Bean工厂”负责创建Bean对象。
      BeanFactory是工厂。
  • FactoryBean
    • FactoryBean:它是一个Bean,是一个能够辅助Spring实例化其它Bean对象的一个Bean。
      在Spring中,Bean可以分为两类:
      • 第一类:普通Bean
      • 第二类:工厂Bean(记住:工厂Bean也是一种Bean,只不过这种Bean比较特殊,它可以辅助Spring实例化其它Bean对象。)

Bean的生存周期

  • 七步生命周期:
    在这里插入图片描述
  • 十步生命周期
    在这里插入图片描述
    Aware相关的接口包括:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware:
    • 当Bean实现了BeanNameAware,Spring会将Bean的名字传递给Bean。
    • 当Bean实现了BeanClassLoaderAware,Spring会将加载该Bean的类加载器传递给Bean。
    • 当Bean实现了BeanFactoryAware,Spring会将Bean工厂对象传递给Bean。
  • 注意:spring只对单例Bean提供生命周期管理,对于多例Bean,Spring只负责到初始化结束,当客户端获取到该Bean时,Spring就不再管理该Bea的n生命周期了。

循环依赖

  • Spring可以在set + singleton模式下解决循环依赖(一个单例一个多例也可以)。
  • 根本的原因在于:这种方式可以做到将“实例化Bean”和“给Bean属性赋值”这两个动作分开去完成。
  • 实例化Bean的时候:调用无参数构造方法来完成。此时可以先不给属性赋值,可以提前将该Bean对象“曝光”给外界。
    也就是说,Bean都是单例的,我们可以先把所有的单例Bean实例化出来,放到一个集合当中(我们可以称之为缓存),所有的单例Bean全部实例化完成之后,以后我们再慢慢的调用setter方法给属性赋值。这样就解决了循环依赖的问题。

反射机制

实例:

package com.powernode.reflect;

import java.lang.reflect.Method;

public class UserTest {
    public static void main(String[] args) throws Exception{
        // 已知类名
        String className = "reflect.User";
        // 已知属性名
        String propertyName = "age";

        // 通过反射机制给User对象的age属性赋值20岁
        Class<?> clazz = Class.forName(className);
        Object obj = clazz.newInstance(); // 创建对象

        // 根据属性名获取setter方法名
        String setMethodName = "set" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);

        // 获取Method
        Method setMethod = clazz.getDeclaredMethod(setMethodName, int.class);

        // 调用Method
        setMethod.invoke(obj, 20);

        System.out.println(obj);
    }
}

Spring IoC注解式开发

  • 注解的存在主要是为了简化XML的配置。Spring6倡导全注解开发。
  • 没仔细研究,后续再补充内容。

AOP介绍

  • 一般一个系统当中都会有一些系统服务,例如:日志、事务管理、安全等。这些系统服务被称为:交叉业务
    这些交叉业务几乎是通用的,不管你是做银行账户转账,还是删除用户数据。日志、事务管理、安全,这些都是需要做的。
    如果在每一个业务处理过程当中,都掺杂这些交叉业务代码进去的话,存在两方面问题:
    • 第一:交叉业务代码在多个业务流程中反复出现,显然这个交叉业务代码没有得到复用。并且修改这些交叉业务代码的话,需要修改多处。
    • 第二:程序员无法专注核心业务代码的编写,在编写核心业务代码的同时还需要处理这些交叉业务。
  • 放一张图快速理解AOP的思想:
    在这里插入图片描述
  • AOP的底层逻辑是通过代理模式(动态代理)实现的,使用了JDK动态代理 + CGLIB动态代理技术。
  • Spring在这两种动态代理中灵活切换,如果是代理接口,会默认使用JDK动态代理,如果要代理某个类,这个类没有实现接口,就会切换使用CGLIB。当然,你也可以强制通过一些配置让Spring只使用CGLIB。
  • 用一句话总结AOP:
    将与核心业务无关的代码独立的抽取出来,形成一个独立的组件,然后以横向交叉的方式应用到业务流程当中的过程被称为AOP。
    AOP的优点:
    • 第一:代码复用性增强。
    • 第二:代码易维护。
    • 第三:使开发者更关注业务逻辑。
  • AOP术语
    • 连接点 Joinpoint
      在程序的整个执行流程中,可以织入切面的位置。方法的执行前后,异常抛出之后等位置。
    • 切点 Pointcut
      在程序执行流程中,真正织入切面的方法。(一个切点对应多个连接点)
    • 通知 Advice
      通知又叫增强,就是具体你要织入的代码。
      • 通知包括:
      • 前置通知
      • 后置通知
      • 环绕通知
      • 异常通知
      • 最终通知
    • 切面 Aspect
      切点 + 通知就是切面。
    • 织入 Weaving
      把通知应用到目标对象上的过程。
    • 代理对象 Proxy
      一个目标对象被织入通知后产生的新对象。
    • 目标对象 Target
      被织入通知的对象。
  • SpringAOP
    Spring对AOP的实现包括以下3种方式:
    第一种方式:Spring框架结合AspectJ框架实现的AOP,基于注解方式。
    第二种方式:Spring框架结合AspectJ框架实现的AOP,基于XML方式。
    第三种方式:Spring框架自己实现的AOP,基于XML配置方式。
  • execution([访问控制权限修饰符] 返回值类型 [全限定类名]方法名(形式参数列表) [异常])
    • 访问控制权限修饰符:
      • 可选项。
      • 没写,就是4个权限都包括。
      • 写public就表示只包括公开的方法。
    • 返回值类型:
      • 必填项。
      • * 表示返回值类型任意。
    • 全限定类名:
      • 可选项。
      • 两个点“…”代表当前包以及子包下的所有类。
      • 省略时表示所有的类。
    • 方法名:
      • 必填项。
      • * 表示所有方法
      • set*表示所有的set方法。
    • 形式参数列表:
      • 必填项
      • () 表示没有参数的方法
      • (…) 参数类型和个数随意的方法
      • ( * ) 只有一个参数的方法
      • ( * , String) 第一个参数类型随意,第二个参数是String的。
    • 异常:
      • 可选项。
      • 省略时表示任意异常类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值