多学习。

【SpringIOC】Spring IOC学习

BeanFactory与ApplicationContext的区别

ApplicationContext:单例模式适用
它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取配置文件就马上创建配置文件中的对象
(可以通过构造函数进行验证)

通过断点验证(在service中加入构造函数):

自定义实现案例:

package com.czy.factory;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


public class BeanFactory {
    //保存配置文件的内容
    private static Properties props;
    private static Map<String,Object> map;

    static {
        props = new Properties();
        try {
            props.load(BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"));
            map = new HashMap<String, Object>();
            Enumeration keys = props.keys();
            while(keys.hasMoreElements()){
                String key = keys.nextElement().toString();
                String value = (String)props.getProperty(key);
                Object bean = Class.forName(value).newInstance();
                map.put(key,bean);
            }
        } catch (Exception e) {
            throw new ExceptionInInitializerError("初始化Properties失败");
        }
    }

    /*public static Object getBean(String beanName){
        if(map.containsKey(beanName))
                return map.get(beanName);
        Object bean = null;
        try{
            bean = Class.forName(props.getProperty(beanName)).newInstance();
            map.put(beanName,bean);
        }catch (Exception e){
            e.printStackTrace();
        }
        return bean;
    }*/

    public static Object getBean(String beanName){
        return map.get(beanName);
    }
}


BeanFactory:多例对象适用
它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象,什么时候才真正的创建对象

通过断点证明:
并没有执行构造函数

用到该对象才创建,执行构造函数

自定义实现案例:

package com.czy.factory;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


public class BeanFactory {
    //保存配置文件的内容
    private static Properties props;
    private static Map<String,Object> map = new HashMap<String, Object>();

    static {
        props = new Properties();
        try {
            props.load(BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"));
        } catch (IOException e) {
            throw new ExceptionInInitializerError("初始化Properties失败");
        }
    }

    public static Object getBean(String beanName){
        if(map.containsKey(beanName))
                return map.get(beanName);
        Object bean = null;
        try{
            bean = Class.forName(props.getProperty(beanName)).newInstance();
            map.put(beanName,bean);
        }catch (Exception e){
            e.printStackTrace();
        }
        return bean;
    }
}


spring对bean的管理细节

1、三种创建Bean对象的方式

第一种方式:适用默认构造函数创建
在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性的标签时,采用的就是默认构造函数创建bean对象,此时如果类中没有默认构造函数,则对象无法创建

第二种方式:使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
工厂类:

package com.czy.factory;

import com.czy.service.AccountService;
import com.czy.service.impl.AccountServiceImpl;

/**
 * 模拟一个工厂类(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认构造函数)
 */

public class InstanceFactory {

    public AccountService getAccountService(){
        return new AccountServiceImpl("a");
    }

}

配置文件:

<?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
        file:///E:\JAVA\spring-framework-5.3.9\schema\beans\spring-beans.xsd">

    <!--第二种方式:使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)-->
    <bean id="instanceFactory" class="com.czy.factory.InstanceFactory"></bean>
    <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>
</beans>

第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
静态方法的工厂类:

package com.czy.factory;

import com.czy.service.AccountService;
import com.czy.service.impl.AccountServiceImpl;

/**
 * 模拟一个工厂类(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认构造函数)
 */

public class StaticInstanceFactory {

    public static AccountService getAccountService(){
        return new AccountServiceImpl("a");
    }

}

配置文件:

    <!--第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)-->
    <bean id="accountService" class="com.czy.factory.StaticInstanceFactory" factory-method="getAccountService"></bean>

2、bean的作用范围

bean默认为单例对象,bean的作用范围调整:
bean标签的scope属性
作用:指定bean的作用范围
取值:
singleton:单例的(默认值)
prototype:多例的
request:作用于web应用的请求范围
session:作用于web应用的会话范围
global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session

 <bean id="accountService" class="com.czy.factory.StaticInstanceFactory" factory-method="getAccountService" scope="prototype"></bean>

3、bean对象的生命周期

单例对象:
出生:容器创建时,对象出生
活着:容器还在,对象一直活着
死亡:容器销毁,对象消亡
总结:单例对象的生命周期和容器相同

多例对象:
出生:当我们使用对象时,spring框架为我们创建
活着:对象还在使用,没有被垃圾回收站回收
死亡:对象被垃圾回收站回收(长时间未使用,且没有被别的对象引用时)

posted @   czyaaa  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示