• Bean的生命周期


    一、Bean的初始化过程

    在这里插入图片描述

    Spring Bean的生命周期

    1)通过XML、Java annotation(注解)以及Java Configuration(配置类)等方式加载Spring Bean
    2)BeanDefinitionReader:解析Bean的定义。在Spring容器启动过程中,会将Bean解析成Spring内部的BeanDefinition结构;理解为:将spring.xml中的标签转换成BeanDefinition结构,有点类似于XML解析
    3)BeanDefinition:包含了很多属性和方法。例如:id、class(类名)、
    scope、ref(依赖的bean)等等。其实就是将bean(例如)的定义信息,存储到这个对应BeanDefinition相应的属性中

    例如:
    -----> BeanDefinition(id/class/scope)

    4)BeanFactoryPostProcessor:是Spring容器功能的扩展接口。
    注意:
    1)BeanFactoryPostProcessor在spring容器加载完BeanDefinition之后,
    在bean实例化之前执行的
    2)对bean元数据(BeanDefinition)进行加工处理,也就是BeanDefinition
    属性填充、修改等操作

    案例:

    package com.zking.beanLife;
    
    public class Demo1 {
    	public static void main(String[] args) {
    		Person p=new Person();
    		p.setSex("男");
    		System.out.println(p.getSex());
    	}
    }
    
    class Person{
    	private String name;
    	private int age;
    	private String sex;
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String getSex() {
    		return sex;
    	}
    	public void setSex(String sex) {
    		this.sex = sex;
    	}
    	public Person() {
    		this.init();
    		this.name="zs";
    		this.age=20;
    		this.sex="未知";
    	}
    	public void init() {
    		
    	}
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    运行效果:

    5)BeanFactory:bean工厂。它按照我们的要求生产我们需要的各种各样的bean。

    案例:

    BeanFactory -> List<BeanDefinition>
    BeanDefinition(id/class/scope/init-method)
    <bean class="com.zking.spring02.biz.BookBizImpl"/>
    foreach(BeanDefinition bean : List<BeanDefinition>){
       //根据class属性反射机制实例化对象
       //反射赋值设置属性
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    6)Aware感知接口:在实际开发中,经常需要用到Spring容器本身的功能资源
    例如:BeanNameAware、ApplicationContextAware等等
    BeanDefinition 实现了 BeanNameAware、ApplicationContextAware

    如图:
    在这里插入图片描述

    7)BeanPostProcessor:后置处理器。在Bean对象实例化和引入注入完毕后,
    在显示调用初始化方法的前后添加自定义的逻辑。(类似于AOP的绕环通知)
    前提条件:如果检测到Bean对象实现了BeanPostProcessor后置处理器才会执行

    案例:

    package com.zking.beanLife;
    
    public class Demo1 {
    	public static void main(String[] args) {
    		Person p=new Person();
    		p.setSex("男");
    		System.out.println(p.getSex());
    	}
    }
    
    class Person{
    	private String name;
    	private int age;
    	private String sex;
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String getSex() {
    		return sex;
    	}
    	public void setSex(String sex) {
    		this.sex = sex;
    	}
    	public Person() {
    		this.init();
    		this.name="zs";
    		this.age=20;
    		this.sex="未知";
    	}
    	public void init() {
    		
    	}
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    	}
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    运行效果:
    在这里插入图片描述

    Before和After方法
    BeanPostProcessor
    1)Before
    2)调用初始化Bean(InitializingBean和init-method,Bean的初始化才算完成)
    3)After

    8)destory:销毁

    2、总结

    ①通过三种方式(配置文件、注解、配置类)将bean标签转成beandifinition对象
    ②通过BeanFactoryPostPricessor可以在初始化之前修改属性
    ③BeanFactory进行bean实例化,就是生产javabean
    ④Aware感知接口,能够在拿到Spring上下文中内部的资源对象
    ⑤BeanPostProcessor后置处理器,相当于环绕通知

    二、Bean的单例与多例模式

    1、多例模式

    scope="prototype"
    
    • 1

    案例:

    package com.zking.beanLife;
    
    public class Demo1 {
    	public static void main(String[] args) {
    		Person p1=new Person();
    		Person p2=new Person();
    		Person p3=new Person();
    		Person p4=new Person();
    		System.out.println(p1);
    		System.out.println(p2);
    		System.out.println(p3);
    		System.out.println(p4);
    	}
    }
    
    class Person{
    	private String name;
    	private int age;
    	private String sex;
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String getSex() {
    		return sex;
    	}
    	public void setSex(String sex) {
    		this.sex = sex;
    	}
    	public Person() {
    		this.init();
    		this.name="zs";
    		this.age=20;
    		this.sex="未知";
    	}
    	public void init() {
    		
    	}
    //	@Override
    //	public String toString() {
    //		return "Person [name=" + name + ", age=" + age + ", sex=" + sex + "]";
    //	}
    //	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    运行效果:
    在这里插入图片描述

    2、单例模式

    在这里插入图片描述

    scope="singLeton"
    
    • 1

    案例:

    package com.zking.beanLife;
    
    public class Demo1 {
    	public static void main(String[] args) {
    //		Person p1=new Person();
    //		Person p2=new Person();
    //		Person p3=new Person();
    //		Person p4=new Person();
    		Person p1=Person.newInstance();
    		Person p2=Person.newInstance();
    		Person p3=Person.newInstance();
    		Person p4=Person.newInstance();
    		System.out.println(p1);
    		System.out.println(p2);
    		System.out.println(p3);
    		System.out.println(p4);
    	}
    }
    
    class Person{
    	private Person() {
    		
    	}
    	
    	private final static Person p=new Person();
    	
    	public static Person newInstance() {
    		return p;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    运行效果:
    在这里插入图片描述

    ①弊端

    在这里插入图片描述

    3、体现单例与多例的区别

    ①InstanceFactory

    package com.zking.beanLife;
    
    public class InstanceFactory {
    	public void init() {
    		System.out.println("初始化方法");
    	}
    
    	public void destroy() {
    		System.out.println("销毁方法");
    	}
    
    	public void service() {
    		System.out.println("业务方法");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    ②ParamAction

    package com.zking.beanLife;
    
    import java.util.List;
    
    public class ParamAction {
    	private int age;
    	private String name;
    	private List<String> hobby;
    	private int num = 1;
    	// private UserBiz userBiz = new UserBizImpl1();
    
    	public ParamAction() {
    		super();
    	}
    
    	public ParamAction(int age, String name, List<String> hobby) {
    		super();
    		this.age = age;
    		this.name = name;
    		this.hobby = hobby;
    	}
    
    	public void execute() {
    		// userBiz.upload();
    		// userBiz = new UserBizImpl2();
    		System.out.println("this.num=" + this.num++);
    		System.out.println(this.name);
    		System.out.println(this.age);
    		System.out.println(this.hobby);
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    ③Demo2

    package com.zking.beanLife;
    
    import org.junit.Test;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.xml.XmlBeanFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.core.io.ClassPathResource;
    import org.springframework.core.io.Resource;
    
    /*
     * spring	bean的生命週期
     * spring	bean的單例多例
     */
    public class Demo2 {
    	// 体现单例与多例的区别
    	@Test
    	public void test1() {
    		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
    //		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
    		ParamAction p1 = (ParamAction) applicationContext.getBean("paramAction");
    		ParamAction p2 = (ParamAction) applicationContext.getBean("paramAction");
    		// System.out.println(p1==p2);
    		p1.execute();
    		p2.execute();
    		
    //		单例时,容器销毁instanceFactory对象也销毁;多例时,容器销毁对象不一定销毁;
    		applicationContext.close();
    	}
    
    	// 体现单例与多例的初始化的时间点 instanceFactory
    	@Test
    	public void test2() {
    		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-context.xml");
    	}
    
    	// BeanFactory会初始化bean对象,但会根据不同的实现子类采取不同的初始化方式
    	// 默认情况下bean的初始化,单例模式立马会执行,但是此时XmlBeanFactory作为子类,单例模式下容器创建,bean依赖没有初始化,只有要获取使用bean对象才进行初始化
    	@Test
    	public void test3() {
    		// ClassPathXmlApplicationContext applicationContext = new
    		// ClassPathXmlApplicationContext("/spring-context.xml");
    
    		Resource resource = new ClassPathResource("/spring-context.xml");
    		BeanFactory beanFactory = new XmlBeanFactory(resource);
    //		InstanceFactory i1 = (InstanceFactory) beanFactory.getBean("instanceFactory");
    		
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    test1运行效果:
    在这里插入图片描述
    test3运行效果:
    ###

  • 相关阅读:
    【附源码】Python计算机毕业设计宿舍管理系统设计
    详解TCP为什么不能是两次握手
    学编程太枯燥太难怎么办?
    第2-3-7章 个人网盘服务接口开发-文件存储服务系统-nginx/fastDFS/minio/阿里云oss/七牛云oss
    10.VueCLI和Vite
    上位机程序,上位机界面开发,ATECLOUD中国人自己的LabVIEW
    pymysql调用存储过程
    无代码开发部门入门教程
    【Linux】Linux中的环境变量及其意义
    react面试题详解
  • 原文地址:https://blog.csdn.net/weixin_67677668/article/details/126233537