Spring

2023年 9月 2日 59.1k 0

Spring 基础与核心概念

spring 是包含了众多工具方法的 IoC 容器。

什么是 IoC ?

IoC = Inversion of Control 翻译成中⽂是“控制反转”的意思,也就是说 Spring 是⼀个“控制反转”的容

器。控制反转,更确切的理解是控制权的反转。要理解控制反转,我们从以下实例出发:

以开发一辆汽车为例:

传统开发:

image.png

控制反转后:

image.png

传统代码是 Car 控制并创建了Framework,Framework 创建并创建了 Bottom,依次往下,⽽改进之后的控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是典型的控制反转,也就是 IoC 的实现思想。

Spring 的核心功能:如何将对象存入到Spring当中,如何从Spring当中获取对象。

DI 介绍:
dependency injection 依赖注入

所谓依赖注⼊,就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。

简单小结:Spring 是一个框架,IoC 是一种思想,DI 是 IoC 的具体实现。

创建Spring项目:

创建一个普通的maven项目:

image.png

image.png

添加Spring依赖:

1.对当前项目和新项目配置国内源:

image.png

image.png

2.更改setting.xml 中的镜像

image.png

3.删除原repository中的文件,重新加载:

image.png

image.png

4.引入依赖:

image.png

添加启动类:

image.png

将Bean对象存储到Spring容器中并获取和使用

  • 创建一个Bean,在Java当中,如果一个类被多次调用,那么就可以称之为Bean.
  • image.png

    2.将Bean存储到spring容器中

    image.png

    3.从Bean中获取对象

    image.png

    image.png

    获取 Bean 的三种方式:

  • 通过名称获取:不推荐
  • image.png

  • 通过类名获取:不推荐
  • image.png

    当一个类在 spring 中存储多份时,使用该方法出错:

    image.png

  • 推荐的方式:通过名称+类名的方式:
  • image.png

    更为简单的存储和获取 Bean 对象的方式:注解

    常用的几大类注解:

    image.png

    image.png

    前置工作:配置扫描路径

    image.png

    image.png

    得到Bean对象:其中得S有两种命名规则,若原类名得第一个字母和第二个字母均为大写,则S为原类名,若不是,则将原类名得第一个字母变为小写后使用:

    image.png

    image.png

    不同包下出现同名类时:在对类进行存储时起别名,否则会报错,尽量避免两个类名相同。

    image.png

    五大类注解有什么关系?

    image.png

    为什么需要五大类注解:

    为了方便程序员更好得区分当前类得作用。

    JavaEE标准分层:

    image.png

    阿里标准分层:

    image.png

    实体类的命名规则:

    image.png

    使用方法注解@Bean 存储对象到spring容器中:

    Bean是将方法得返回值存入spring,因此使用Bean注解得方法必须有返回值。

    image.png

    Bean 重命名:

    image.png

    同一个类型的对象存储多份时,后者会将前者覆盖,通过@Order注解来控制存入的顺序,值为1-100,数字越小先存入,后者将前者覆盖。

    image.png

    image.png

    输出结果为:张三。

    获取Bean对象

    在当前基于Spring_core 框架的项目中,无法在启动类的main方法中获取到Bean对象,因为当前static修饰的类加载优先于Bean。

    1.属性注入

    image.png

    单一设计原则:一个类只实现一个功能,当一个类中通过属性注入多个对象时,就会违背单一设计原则。

    2.setter注入

    image.png

    3.构造方法的注入

    image.png

    @Resource 和 @Autowired 的区别:

    1.两者来源不同,前者来自 JDK,后者来自 Spring.

    2.两者都可以用于对象注入,但是前者不能用于构造方法的注入

    3.前者拥有更多的属性内容,后者只有是否必须加载一个属性:

    image.png

    4.在Spring容器中,查找Bean的方式有两种,一种是按照类型查找,一种是按照名称查找,@Autowired 注解先根据类型查找,再根据名称查找,而@Resource注解刚好相反。

    Lombok 的使用

  • 引入依赖:
  • image.png

  • 在实体类上使用其提供的注解
  • image.png

  • 装Lombok插件:
  • image.png

    Bean 的作用域和生命周期

    先来看一个例子:

    创建实体类:

    image.png

    原始数据:

    image.png

    在controller中分别注入当前的数据,并在第一个中进行数据修改:

    image.png

    image.png

    在启动程序中调用两个controller:

    image.png

    此时,我们发现,当一个Bean被修改后,别处获取到的Bean数据也发生了改变。

    Bean 作用域默认是单例模式 = 该 Bean 在整个spring容器中只存在一份。

    image.png

    image.png

    spring 的执行流程:

    image.png

    Bean 的生命周期:从诞生到销毁

  • 开辟内存空间,进行Bean的实例化;

  • 设置属性(属性注入):在初始化时可能会使用到属性,因此要先进行属性注入;

  • 初始化

    3.1 各种通知

    3.2 初始化前置方法

    3.3 初始化方法(两种实现方式,一种是xml,一种是通过注解)

    3.4 初始化后置方法

  • 使用Bean

  • 销毁Bean

  • 代码示例:

    public class ComponentBeans implements BeanNameAware, BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化前置方法");
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化后置方法");
            return  bean;
        }
    
        @Override
        public void setBeanName(String s) {
            System.out.println("通知 setBeanName "+ s);
        }
    
        public void myInit(){
            System.out.println("XML 方式的初始化方法");
        }
    
        @PostConstruct
        public void doPostConstruct(){
            System.out.println("注解方式的初始化方法");
        }
    
        public void saiHi(){
            System.out.println("使用Bean");
        }
    
        @PreDestroy
        public void doPreDestroy(){
            System.out.println("执行了销毁方法");
        }
    }
    
    public class App {
        public static void main(String[] args) {
            ClassPathXmlApplicationContext context =
                    new ClassPathXmlApplicationContext("spring-config.xml");
            ComponentBeans componentBeans = context.getBean("componentBeans",ComponentBeans.class);
            componentBeans.saiHi();
            context.close();
        }
    }
    

    输出结果:

    image.png

    说明:

  • 为何通知执行了两次,一次是在new 对象时进行初始化,一次是在getBean 时初始化;

  • 为何没有执行销毁方法,因为多例模式下,销毁bean是直接停止线程,故不会执行销毁时的方法。

  • 前置方法和后置方法只有作用域为原型模式时才执行。

  • 相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论