【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框架为我们创建
活着:对象还在使用,没有被垃圾回收站回收
死亡:对象被垃圾回收站回收(长时间未使用,且没有被别的对象引用时)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!