我Spring系列一:spring的安装与使用

2025-11-17 18:05:02

判断是否是懒加载: 是事先创建好, 还是等到用户使用的时候再创建. lazyInit: false. 说明beans.xml中对象的创建不是懒加载.

1.在com.zzw.spring.test.SpringBeanTest的getMonster方法处打断点 用Debug的方式, 看一下Spring容器的处理机制 ioc->beanFactory->beanDefinitionMap

beanDefinitionMap / table

index=217 table / propertyValues

beanFactory->singletonObjects singletonObjects / table

beanFactory / beanDefinitionNames

题目: 查看容器注入了哪些bean对象, 输出bean的id

解答: 在com.zzw.spring.test.SpringBeanTest的getMonster方法里增加下端代码, 测试

String[] beanDefinitionNames = ioc.getBeanDefinitionNames();

for (String beanDefinitionName : beanDefinitionNames) {

System.out.println("beanDefinitionName=" + beanDefinitionName);

}

🍊Debug配置

小技巧分享

ioc->beanFactory->beanDefinitionMap

💞实现简单基于XML配置程序

需求说明

自己写一个简单的Spring容器, 通过读取beans.xml, 获取第1个JavaBean: Monster的对象, 并给该对象的属性赋值, 放入到容器中, 并输出该对象信息也就是说, 不使用Spring原生框架, 我们自己简单模拟实现了解Spring容器的简单机制

思路分析

●代码实现 1.引入dom4j-1.6.1.jar包

2.新建com.zzw.spring.zzwapplicationcontext.ZzwApplicationContext.java

/**

* @author 赵志伟

* @version 1.0

* 1.这个程序用于实现Spring的一个简单容器机制

* 2.后面还会详细实现

* 3.这里我们实现如何将beans.xml文件进行解析, 并生成对象, 放入容器中

* 4.提供一个方法 getBean(id) 返回对应的对象

* 5.这里就是一个开胃小点心, 理解Spring容器的机制

*/

@SuppressWarnings({"all"})

public class ZzwApplicationContext {

private ConcurrentHashMap singletonObjects = new ConcurrentHashMap<>();

//构造器

//接收一个容器的配置文件 比如 beans.xml, 该文件默认在src目录下

public ZzwApplicationContext(String iocBeanXmlFile) throws Exception {

//1.得到类加载路径:

// /D:/idea_project/zzw_spring/spring/out/production/spring/

String path = this.getClass().getResource("/").getPath();

//2.创建解析器

SAXReader reader = new SAXReader();

//3.得到document对象

Document document = reader.read(new File(path + iocBeanXmlFile));

//4.获取rootElement

Element rootElement = document.getRootElement();

//5.得到第1个bean-monster01

Element bean = (Element) rootElement.elements("bean").get(0);

//6.获取第一个bean-monster01的相关属性 => beanDefinitionMap

String id = bean.attributeValue("id");

String ClassFullPath = bean.attributeValue("class");

List properties = bean.elements("property");

//这里不再遍历, 直接获取

Integer monsterId = Integer.parseInt(properties.get(0).attributeValue("value"));

String name = properties.get(1).attributeValue("value");

String skill = properties.get(2).attributeValue("value");

//7.使用反射创建对象 => 回顾反射机制

Class aClass = Class.forName(ClassFullPath);

//这里instance就是Monster对象

Monster o = (Monster) aClass.newInstance();

//给o对象通过反射来赋值 => 这里先简化

o.setMonsterId(monsterId);

o.setName(name);

o.setSkill(skill);

//8.将创建好的对象放入到singletonObjects

singletonObjects.put(id, o);

}

public Object getBean(String id) {

//这里可以再处理一下

return singletonObjects.get(id);

}

//加上泛型

public T getBean(String beanName, T t) {

return (T) singletonObjects.get(beanName);

}

}

3.测试 com.zzw.spring.ZzwApplicationContextTest

public class ZzwApplicationContextTest {

public static void main(String[] args) throws Exception {

ZzwApplicationContext ioc = new ZzwApplicationContext("beans.xml");

Monster monster01 = (Monster) ioc.getBean("monster01");

System.out.println("monster01=" + monster01);

System.out.println("monster01.name=" + monster01.getName());

System.out.println("ok~");

}

}

🍊Spring原生容器结构梳理

🍊作业布置

问: 在beans.xml中, 注入两个Monster对象, 但是不指定id, 运行会不会报错? 如果不会报错. 如何知道id, 并获取Monster对象.

答: 1.不会报错, 会正常运行 2.系统会默认分配id. 分配id的规则是: 全类名#0, 全类名#1 这样的规则来分配id的. 例如 com.zzw.spring.bean.Monster#0, com.zzw.spring.bean.Monster#1

3.让我们通过debug方式来查看

●代码实现 1.测试src/com/zzw/spring/test/SpringBeanTest.java

public class SpringBeanTest {

@Test

public void getMonster() {

//1.创建容器, 习惯用接口的形式接收

ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");

Monster monster1 = ioc.getBean("com.zzw.spring.bean.Monster#0", Monster.class);

System.out.println("monster1=" + monster1);

Monster monster2 = ioc.getBean("com.zzw.spring.bean.Monster#1", Monster.class);

System.out.println("monster2=" + monster2);

System.out.println("ok~");

}

}

🍊Spring课堂练习

创建一个Car类, 要求 1.创建ioc容器文件(配置文件), 并配置一个Car对象(bean). 2.通过java程序到ioc容器获取该bean对象, 并输出

1.新建com.zzw.spring.bean.Car

public class Car {

private Integer id;

private String name;

private Double price;

public Car() {

System.out.println("car对象 无参构造器被执行");

}

//有参构造器, setter, getter, toString()

2.新建src/beans1.xml

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">

3.测试src/com/zzw/spring/test/SpringBeanTest.java

@Test

public void getCar() {

//1.创建容器对象

ApplicationContext ioc = new ClassPathXmlApplicationContext("beans1.xml");

Car car01 = ioc.getBean("car01", Car.class);

System.out.println("car01=" + car01);

System.out.println("car01.name=" + car01.getName());

System.out.println("ok~");

}

}

🔜 下一篇预告: Spring系列二:基于XML配置bean 上

📚 目录导航 📚

Spring系列一:spring的安装与使用Spring系列二:基于XML配置bean 上Spring系列二:基于XML配置bean 中Spring系列二:基于XML配置bean 下Spring系列三:基于注解配置bean 上Spring系列三:基于注解配置bean 中Spring系列三:基于注解配置bean 下

💬 读者互动 💬 在学习 Spring 安装与使用的过程中,您有哪些新的发现或疑问?欢迎在评论区留言,让我们一起讨论吧!😊