首页 > 其他分享 >Spring的生命周期

Spring的生命周期

时间:2023-03-04 20:56:25浏览次数:29  
标签:生命周期 Spring System Orders bean println public out

Spring 概述

  1. Spring 是一个 轻量级的 J2EE 开源框架
  2. 可以解决企业应用开发的复杂性
  3. Spring 的核心部分:IOC 和 AOP
  4. 特点
    • 方便解耦,简化开发
    • AOP 编程
    • 方便程序测试
    • 方便与其他框架整合
    • 方便事务操作
    • 降低API开发难度

IOC(控制反转)

把对象的创建和对象间的调用交给 Spring容器管理

目的: 降低 耦合度

底层原理:

  • xml解析
  • 工厂模式
  • 反射

IOC思想

  1. IOC 思想基于 IOC容器完成, IOC 容器底层 就是 对象工厂

  2. Spring 提供IOC容器的两个接口(方法)

    • BeanFactory: IOC 容器基本实现,是Spring内部的使用接口,不提供给开发者使用

      加载配置文件的时候不会创建对象,只有使用的时候才会创建对象(懒汉式)

    • ApplicationContext: BeanFactory 的子接口,提供更强大的功能

      加载配置文件就会创建对象

ICO操作 Bean管理

  1. 基于 xml 文件
  2. 基于注解

DI(依赖注入)

DI 是 IOC中的一种具体实现,DI 需要在创建对象的基础之上完成

Bean的生命周期

五步

  1. 通过构造器创建Bean实例(无参构造)
  2. 属性注入(为Bean的属性设置值,或者对 其他Bean 引用)
  3. 调用 Bean 的初始化方法(需要进行配置)
  4. 使用
  5. 销毁(需要配置销毁的方法)

七步(多出的两部分别在 初始化前后执行)

这个是使用 bean 的后置处理器 BeanPostProcessor (要在配置文件中配置才能生效)

创建一个类 实现 BeanPostProcessor,重写方法

前置增强postProcessBeforeInitialization

后置增强 postProcessAfterInitialization

  1. 通过构造器创建Bean实例(无参构造)
  2. 属性注入(为Bean的属性设置值,或者对 其他Bean 引用)
  3. postProcessBeforeInitialization前置增强
  4. 调用 Bean 的初始化方法(需要进行配置)
  5. postProcessAfterInitialization后置增强
  6. 获取
  7. 销毁

把代码第四步❌剔除

MyBeanPostProcessor.java后置处理器

package com.bikakaso.processor;
import com.bikakaso.pojo.Orders;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import javax.annotation.PostConstruct;

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("3. 我是前置增强");
        if (bean instanceof Orders) {
            Orders orders = (Orders) bean;
            orders.setName("截胡了");
            return orders;
        }

        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("6. 后置增强");
        if (bean instanceof Orders) {
            Orders orders = (Orders) bean;
            orders.setName("不好意思,不让你截");
            return orders;
        }
        return bean;
    }
}

Orders.java实体类

package com.bikakaso.pojo;

import org.springframework.beans.factory.InitializingBean;

public class Orders implements InitializingBean {
    private String name;
    private double price ;
    int i = 1;

    public void setPrice(double price) {
        this.price = price;
        if ( i == 1) {
            System.out.println("调用 setPrice 方法");
        }
        i++;
    }

    public Orders() {
        System.out.println(" 1. 调用 无参构造");
    }

    public void setName(String name) {
        this.name = name;
        if ( i == 1) {
            System.out.println("2.调用 setName 方法");
        }
        i++;

    }

    public void initMethod() {
        System.out.println("5. 初始化方法,这个步骤需要自己配置");
    }
    public void destroyMethod() {
        System.out.println("8. 销毁bean");
    }

    @Override
    public String toString() {
        return "Orders{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
   
   // 这一步 实体类需要实现 InitializingBean 接口
    
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("4. 前置处理后,初始化前");
    }
}


bean2.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="orders" class="com.bikakaso.pojo.Orders"  init-method="initMethod" destroy-method="destroyMethod">
        <property name="name" value="订单1"/>
    </bean>
    <bean id="myBeanPostProcessor" class="com.bikakaso.processor.MyBeanPostProcessor"/>
</beans>

测试

    @Test
    public void test2() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean2.xml");
        Orders orders = applicationContext.getBean("orders", Orders.class);
//        Orders orders2 = applicationContext.getBean("orders", Orders.class);
        System.out.println("7. 获取到 bean");
        System.out.println(orders.toString());
        applicationContext.close();
    }

xml自动装配(自动注入)

byName

根据定义的属性名 注入,配置文件中的 bean 的 id 需要和 属性名相同

但是 byName 找不到 相同的 id 时,还会再根据 类型注入

Empl.java

public class Empl {
    // 自动装配 byName, 配置文件中 通过 dept 这个名字 注入属性
    private Dept dept;
    private Dept dept1; // 测试 根据类型注入,3行需注释,重写 set 方法
    public void setDept(Dept dept) {
        this.dept = dept;
    }
    
    @Override
    public String toString() {
        return "Empl{" +
                "dept=" + dept +
                '}';
    }
}

Dept.java

public class Dept {
    @Override
    public String toString() {
        return "Dept{}";
    }
}

bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
        xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="empl" class="com.bikakaso.autowire.Empl" autowire="byName"/>
    <bean id="dept" class="com.bikakaso.autowire.Dept"/>
   <bean id="dept1" class="com.bikakaso.autowire.Dept"/> // 测试根据类型注入,10行需注释
</beans>

测试

 // 自动装配
    @Test
    public void test3() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean3.xml");
        Empl empl = applicationContext.getBean("empl", Empl.class);
        System.out.println(empl.toString());
    }

结果

正常情况

image-20230304200127694

找不到 name

image-20230304200023599

byType

byType 是根据 bean 的 class 属性来注入的,同一个类的 bean 只能存在一个,否则会报错

image-20230304200550598

AOP

标签:生命周期,Spring,System,Orders,bean,println,public,out
From: https://www.cnblogs.com/Bikakaso/p/spring.html

相关文章

  • SpringBoot开发实用-配置
    2.配置高级​ 进入开发实用篇第二章内容,配置高级,其实配置在基础篇讲了一部分,在运维实用篇讲了一部分,这里还要讲,讲的东西有什么区别呢?距离开发过程越来越接近,解决的问题也......
  • java-spring纯注解开发
    1、创建配置类替代配置文件/***<p>描述:配置信息,省去编写配置文件*/@Configuration@ComponentScan("cn.tjhis")publicclassSpringConfig{}2、实现类......
  • SpringMVC:文件上传下载如何实现?
      一、文件下载如果在响应时候没有设置响应头中的Content-Disposition属性,则会使用默认值inline,此时客户端访问静态资源的时候,能解析显示的就会解析显示,不能解析......
  • java-spring 通过配置文件获取bean
    1、druid.properties#mysql连接参数jdbc.driver-class-name=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/wangdb?useUnicode=true&characterEncodi......
  • Spring事务失效的十种常见场景
    目录概述事务的传播类型isolation@Transactionnal注解属性Spring事务失效的场景:1.事务方法未被Spring管理2.方法使用final类型修饰3.非public修饰的方法4.同一个类中......
  • docker搭建maven私服(nexus3),整合springboot上传下载依赖
    一、前言我们在JavaWeb开发中必不可少的就是jar包管理-maven,在没有maven之前,都是自己手动下载jar包导入到项目中,非常的繁琐。maven出现之后,又迎来新的问题,对于仓库里人家......
  • Spring扩展
    目录Spring扩展1.自定义拦截器2.获取Spring容器对象2.1BeanFactoryAware接口2.2ApplicationContextAware接口2.3ApplicationListener接口3.全局异常处理4.类型转换器5.......
  • java——spring boot集成kafka——kafka介绍以及概念理解
                  首先,让我们来看一下基础的消息(Message)相关术语:名称解释Broker消息中间件处理节点,⼀个Kafka节点就是⼀个broker,⼀个......
  • java——spring boot集成kafka——消息队列的流派
                   ......
  • spring学习笔记
    Spring学习笔记官方下载地址:https://repo.spring.io/libs-release-local/org/springframework/spring/GitHub:https://github.com/spring-projects<!--https://mv......