day01_ioc

1 概念

框架:大师写好的半成品
spring框架:不是功能性框架(不属于某一层) 用于整合其他功能框架的中间层框架
核心:ioc和aop
ioc:Inversion of Control,控制反转
    把程序中需要对象的创建 初始化 维护 分配 销毁等交给spring容器来管理
    程序中需要的所有对象 不需要new 而是从spring容器中拿
di: Dependency Injection,依赖注入
    在运行时 把需要的对象动态的注入到程序中

2 案例1

2.1 导入jar包

logging-1.1.1.jar:日志jar
log4j-1.2.15.jar:日志jar
asm-3.0.1.RELEASE-A.jar:字节码文件解析jar
RELEASE-A.jar:javabean实体类依赖的jar
context-3.0.1.RELEASE-A.jar:spring功能控制jar---验证/jmail
core-3.0.1.RELEASE-A.jar:springioc核心jar
expression-3.0.1.RELEASE-A.jar:spring表达式依赖的jar

2.2 创建核心配置文件

  • 名字随意
spring_config.xml
  • xml文件声明区和根标签(xsd文件的引入)
<?xml version="1.0" encoding="UTF-8"?>
<beans 	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	<!-- xsd文件对当前xml文件进行语法检查 :规定有哪些标签 有哪些属性 标签的嵌套关系-->
	
</beans>xxxxxxxxxx spring_config.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"    xmlns:p="http://www.springframework.org/schema/p"    xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    http://www.springframework.org/schema/context     http://www.springframework.org/schema/context/spring-context-3.0.xsd">    <!-- xsd文件对当前xml文件进行语法检查 :规定有哪些标签 有哪些属性 标签的嵌套关系-->    </beans>xml

2.3 创建实体类

1 实现序列化
2 所有属性私有化:提供getset方法
3 提供无参数的构造方法
4 属性包装类类型
public class Student   implements Serializable{
	private Integer sid;
	private String sname;
	private Integer sage;
	private Boolean sdy;
	private Float score;
    ...
}

2.4 在核心配置文件中通过bean标签来创建对象

<!-- 通过bean标签来创建对象:1 通过property标签给属性赋值 -->
<bean id="stu1" class="com.zhiyou100.test01.Student">  <!-- class指定对象的类型 id指定对象的引用名 -->
    <property name="sid" value="1001"/><!-- property标签:给指定的属性赋值 -->
    <property name="sname" value="韩梅梅"/><!-- property标签:给指定的属性赋值 -->
    <property name="sage" value="19"/><!-- property标签:给指定的属性赋值 -->
    <property name="sdy" value="true"/><!-- property标签:给指定的属性赋值 -->
    <property name="score" value="11.6"/><!-- property标签:给指定的属性赋值 -->
</bean>
<!-- 通过bean标签来创建对象:2 通过构造方法参数列表给属性赋值 -->
<bean id="stu2" class="com.zhiyou100.test01.Student">  <!-- class指定对象的类型 id指定对象的引用名 -->
    <!-- Integer sid, String sname, Integer sage, Boolean sdy, Float score -->
    <constructor-arg name="sid" value="1002"/>
    <constructor-arg name="sname" value="韩寒"/>
    <constructor-arg name="sage" value="19"/>
    <constructor-arg name="sdy" value="false"/>
    <constructor-arg name="score" value="33.5"/>
</bean>
<bean id="stu3" class="com.zhiyou100.test01.Student">  <!-- class指定对象的类型 id指定对象的引用名 -->
    <!-- Integer sid, String sname, Integer sage, Boolean sdy, Float score -->
    <constructor-arg index="0" value="1003"/>
    <constructor-arg index="1" value="韩非子"/>
    <constructor-arg index="2" value="29"/>
    <constructor-arg index="3" value="false"/>
    <constructor-arg index="4" value="35.5"/>
</bean>

2.5 测试类

//1 创建springcontext对象 加载核心配置文件
ClassPathXmlApplicationContext context=
    new ClassPathXmlApplicationContext("com/zhiyou100/test01/spring_config.xml");
//2 获取bean对象
Student s1=(Student)context.getBean("stu1");
System.out.println(s1);
Student s2=(Student)context.getBean("stu2");
System.out.println(s2);
Student s3=(Student)context.getBean("stu3");
System.out.println(s3);
//3 关闭容器
context.close();

2.6 结果

image-20221223094912965

3 注意事项

1:默认情况下:项目一启动,springcontext上下文对象就加载核心配置文件 立刻为每个bean标签创建对象
2:默认情况下:一个bean标签只对应一个对象:每个bean都是一个单例对象
3:property标签给属性赋值:必须提供无参数的构造方法:否则报错:NoSuchMethodException
                        对象创建后 提供调用set方法给属性赋值
4:constructor-arg标签给属性赋值:调用对应的构造方法 通过构造方法的参数列表给属性赋值

4 上下文对象的创建

//1 springcontext上下文对象的创建方式1:ClassPathXmlApplicationContext:相对位置是src
ClassPathXmlApplicationContext context1=
    new ClassPathXmlApplicationContext("com/zhiyou100/test01/spring_config.xml");
Student s11=(Student)context1.getBean("stu1");
System.out.println(s11);
context1.close();

//2 springcontext上下文对象的创建方式2:FileSystemXmlApplicationContext:相对位置是项目路径
FileSystemXmlApplicationContext context2=
    new FileSystemXmlApplicationContext("src/com/zhiyou100/test01/spring_config.xml");
Student s12=(Student)context2.getBean("stu1");
System.out.println(s12);
context2.close();

5 多核心配置文件

5.1 方式1:ClassPathXmlApplicationContext构造方法是不定参数

//1 ClassPathXmlApplicationContext构造方法参数是不定参数:可以一次加载多个配置文件
ClassPathXmlApplicationContext context1=
    new ClassPathXmlApplicationContext("com/zhiyou100/test01/spring_config01.xml","com/zhiyou100/test01/spring_config02.xml");
Student s11=(Student)context1.getBean("stu1");
System.out.println(s11);
Student s12=(Student)context1.getBean("stu2");
System.out.println(s12);
context1.close();

5.2 方式2:定义一个总的配置文件:通过import引入其他配置文件

  • spring_config03.xml
<!-- 引入其他配置文件 -->
<import resource="spring_config01.xml"/>
<import resource="spring_config02.xml"/>
  • 创建ClassPathXmlApplicationContext只需要加载总的核心配置文件即可
//2 直接加载总的核心配置文件即可
ClassPathXmlApplicationContext context2=
    new ClassPathXmlApplicationContext("com/zhiyou100/test01/spring_config03.xml");
Student s111=(Student)context2.getBean("stu1");
System.out.println(s111);
Student s122=(Student)context2.getBean("stu2");
System.out.println(s122);
context1.close();

6 对象关联

6.1 创建teacher类

public class Teacher implements Serializable{
	private Integer tid;
	private String tname;
	private String tsex;
    ...
}

6.2 在student类中定义引用指向其关联的teacher对象

public class Student   implements Serializable{
	...
	private Teacher teacher;
    ...
}

6.3 在核心配置文件中为teacher定义bean 并在student的bean中通过ref来关联此对象

<!-- 通过bean标签来创建对象:1 通过property标签给属性赋值 -->
<bean id="stu1" class="com.zhiyou100.test01.Student">  <!-- class指定对象的类型 id指定对象的引用名 -->
    <!-- property标签 通过调用对象的set方法给属性赋值 -->
    <property name="sid" value="1001"/><!-- property标签:给指定的属性赋值 -->
    <property name="sname" value="韩梅梅"/><!-- property标签:给指定的属性赋值 -->
    <property name="sage" value="19"/><!-- property标签:给指定的属性赋值 -->
    <property name="sdy" value="true"/><!-- property标签:给指定的属性赋值 -->
    <property name="score" value="11.6"/><!-- property标签:给指定的属性赋值 -->
    <property name="teacher" ref="tea1"/><!-- 指定当前student的teacher属性的值为id=tea1的bean对象 -->
</bean>
<bean id="tea1" class="com.zhiyou100.test01.Teacher">
    <property name="tid" value="1"/>
    <property name="tname" value="高老师"/>
    <property name="tsex" value=""/>
</bean>
<bean id="stu2" class="com.zhiyou100.test01.Student">  <!-- class指定对象的类型 id指定对象的引用名 -->
    <!-- Integer sid, String sname, Integer sage, Boolean sdy, Float score -->
    <constructor-arg index="0" value="1003"/>
    <constructor-arg index="1" value="韩非子"/>
    <constructor-arg index="2" value="29"/>
    <constructor-arg index="3" value="false"/>
    <constructor-arg index="4" value="35.5"/>
    <constructor-arg index="5" ref="tea1"/>
</bean>

6.4 测试

ClassPathXmlApplicationContext context2=
    new ClassPathXmlApplicationContext("com/zhiyou100/test01/spring_config04.xml");
Student s111=(Student)context2.getBean("stu1");
System.out.println(s111);
Student s1112=(Student)context2.getBean("stu2");
System.out.println(s1112);
context2.close();

7 bean的作用域

<!--  通过bean的scope属性来指定bean对象的作用域:默认是singleton::单例::一个bean标签只创建一个对象::
	                                       此单例对象::核心配置文件已加载就创建
	             通过bean的scope属性来指定bean对象的作用域:prototype::多例::每次bean标签调用都创建一个新的对象
	                                           prototype的对象::getBean方法调用时才创建
	              通过bean的scope属性来指定bean对象的作用域:request:::针对于web项目::每个请求链对应同一个bean对象
	              通过bean的scope属性来指定bean对象的作用域:session:::针对于web项目::每个回话对应同一个bean对象
	              通过bean的scope属性来指定bean对象的作用域:global-session:::针对于web项目::整个项目对应同一个bean对象
-->
	<bean id="tea1" class="com.zhiyou100.test02.Teacher"  scope="singleton">
	    <property name="tid" value="1"/>
	    <property name="tname" value="高老师"/>
	    <property name="tsex" value=""/>
	</bean>
	<bean id="tea2" class="com.zhiyou100.test02.Teacher"  scope="prototype">
	    <property name="tid" value="2"/>
	    <property name="tname" value="高老师"/>
	    <property name="tsex" value=""/>
	</bean>

8 bean的懒加载

<!-- 懒加载:针对于单例模式::单例模式默认情况下是 核心配置文件一创建 此对象就创建
                          可以通过 lazy-init="true" 来指定第一次调用getbean方法时 才创建此对象        
    -->
<bean id="tea1" class="com.zhiyou100.test02.Teacher"  scope="singleton">
    <property name="tid" value="1"/>
    <property name="tname" value="高老师"/>
    <property name="tsex" value=""/>
</bean>
<bean id="tea2" class="com.zhiyou100.test02.Teacher"  scope="singleton" lazy-init="true">
    <property name="tid" value="2"/>
    <property name="tname" value="高老师"/>
    <property name="tsex" value=""/>
</bean>

9 工厂模式

工厂模式:a对象的创建 交给b工厂对象的方法来实现

9.1 静态工厂模式::工厂对象的方法是静态方法

  • 创建静态工厂类
public class TeacherFactoryStatic {
	public static Teacher getInstance(){
		return new Teacher(1001, "韩雪", "女");
	}
}
  • 配置文件中通过静态工厂类的军团方法创建bean
<!-- 静态工厂模式:对象的创建由工厂对象的静态方法来实现     -->
<bean id="tea1" class="com.zhiyou100.test02.TeacherFactoryStatic"   factory-method="getInstance" />

9.2 实例工厂模式::工厂对象的方法是实例方法

  • 创建实例工厂类
public class TeacherFactoryInstance {
	public  Teacher getInstance(){
		return new Teacher(1001, "韩雪", "女");
	}
}
  • 配置文件中先创建工厂bean 在提供工厂bean的实例方法获取对象
<!-- 实例工厂模式:对象的创建由工厂对象的实例方法来实现     -->
<!--  创建实例工厂对象 -->
<bean id="factory" class="com.zhiyou100.test02.TeacherFactoryInstance"  />
<!-- 通过工厂类对象的实例方法创建bean -->
<bean id="tea2" class="com.zhiyou100.test02.Teacher"  factory-bean="factory" factory-method="getInstance" />

10 bean的生命周期

10.1 更改实体类:添加方法

package com.zhiyou100.test02;

import java.io.Serializable;

public class Teacher implements Serializable{
	....
	
	public void methodInit(){
		System.out.println("初始化方法:::public void methodInit()");
	}
	public void methodDestroy(){
		System.out.println("销毁方法:::public void methodDestroy()");
	}
	
}

10.2 在核心配置文件中 通过属性init-method和destroy-method 指定初始化方法和销毁方法

<!-- bean的生命周期:bean对象的创建 初始化 调用 及其销毁的整个过程
 1 对象创建::默认情况下 核心配置文件一加载 spring容器就创建bean的唯一对象
 2 对象初始化::对象一旦创建 spring容器就会立刻调用bean的init-method方法 对对象进行初始化
 3 对象销毁::当spring容器销毁前 会调用bean的destroy-method方法 销毁对象 释放内存
  -->
<bean id="tea1" class="com.zhiyou100.test02.Teacher" init-method="methodInit" destroy-method="methodDestroy">
    <property name="tid" value="1"/>
    <property name="tname" value="高老师"/>
    <property name="tsex" value=""/>
</bean>

11 bean的集合属性的赋值

11.1 创建实体类

public class Student implements Serializable{
	private Integer sid;
	private String sname;
	private Float[] arr;
	private List<Teacher> listTeas;
	private Set<Integer> setInts;
	private Map<Integer, String> mapProperty;
    ...
}

11.2 在配置文件中给属性赋值

<!-- 给集合类型的属性赋值 -->
<bean id="stu1" class="com.zhiyou100.test02.Student">
    <!-- 给单值属性赋值 -->
    <property name="sid" value="1001"/>
    <property name="sname" value="韩梅梅"/>
    <!-- 给数组类型的属性赋值:private Float[] arr; -->
    <property name="arr">
        <array value-type="java.lang.Float">
            <value>111.2</value>
            <value>112.2</value>
            <value>113.2</value>
            <value>114.2</value>
        </array>
    </property>
    <!-- 给数list类型的属性赋值:private List<Teacher> listTeas; -->
    <property name="listTeas">
        <list value-type="com.zhiyou100.test02.Teacher">
            <ref bean="tea11"/>
            <ref bean="tea12"/>
            <ref bean="tea13"/>
            <ref bean="tea12"/>
            <ref bean="tea11"/>
        </list>
    </property>
    <!-- 给数set类型的属性赋值:private Set<Integer> setInts; -->
    <property name="setInts">
        <set value-type="java.lang.Integer">
            <value>121</value>
            <value>122</value>
            <value>123</value>
            <value>121</value>
        </set>
    </property>
    <!-- 给数map类型的属性赋值:Map<Integer, String> mapProperty; -->
    <property name="mapProperty">
        <map key-type="java.lang.Integer" value-type="java.lang.String">
            <entry key="111" value="v_111"/>
            <entry key="112" value="v_112"/>
            <entry key="113" value="v_113"/>
            <entry key="114" value="v_114"/>
        </map>
    </property>
</bean>
<bean id="tea11" class="com.zhiyou100.test02.Teacher">
    <property name="tid" value="11"/>
    <property name="tname" value="高老师1"/>
    <property name="tsex" value=""/>
</bean>
<bean id="tea12" class="com.zhiyou100.test02.Teacher">
    <property name="tid" value="12"/>
    <property name="tname" value="高老师2"/>
    <property name="tsex" value=""/>
</bean>
<bean id="tea13" class="com.zhiyou100.test02.Teacher">
    <property name="tid" value="13"/>
    <property name="tname" value="高老师3"/>
    <property name="tsex" value=""/>
</bean>

12 bean的自动装配

12.1 修改Student

public class Student implements Serializable{
	private Integer sid;
	private String sname;
	private Teacher tea;
    ...
}

12.2 自动装配和手动装配

<!-- 不给tea属性赋值  tea属性就没有值-->
<bean id="stu1" class="com.zhiyou100.test02.Student">
    <!-- 给单值属性赋值 -->
    <property name="sid" value="1001"/>
    <property name="sname" value="韩梅梅"/>
</bean>
<!-- 通过ref给tea属性赋值::手动装配::通过ref 手动给对象类型的属性赋值 -->
<bean id="stu2" class="com.zhiyou100.test02.Student">
    <!-- 给单值属性赋值 -->
    <property name="sid" value="1002"/>
    <property name="sname" value="韩梅梅"/>
    <property name="tea" ref="t1"></property>
</bean>
<!-- 自动装配: 通过autowire指定实现对象的关联-->
<!-- No unique bean of type [com.zhiyou100.test02.Teacher] is defined: expected single matching bean but found 2: [t1, t2] -->
<!-- autowire="byType"::自动给对象类型的赋值对应类型的bean -->
<!-- autowire="byType"::如果此类型的bean只要一个::  直接赋值-->
<!-- autowire="byType"::如果此类型的bean有多个::  赋值和属性名相同的bean-->
<!-- autowire="byType"::如果此类型的bean有多个,并且没有和属性名相同的bean::报错No unique bean of type-->
<!-- autowire="byName"::找和属性同名的bean赋值::如果没有同名的::就不赋值::那就是null-->
<bean id="stu3" class="com.zhiyou100.test02.Student" autowire="byName">
    <!-- 给单值属性赋值 -->
    <property name="sid" value="1003"/>
    <property name="sname" value="韩梅梅"/>
</bean>
<bean id="t1" class="com.zhiyou100.test02.Teacher">
    <property name="tid" value="121"/>
    <property name="tname" value="高老师21"/>
    <property name="tsex" value=""/>
</bean>
<bean id="t2" class="com.zhiyou100.test02.Teacher">
    <property name="tid" value="122"/>
    <property name="tname" value="高老师22"/>
    <property name="tsex" value=""/>
</bean>

13 注解形式的ioc

13.1 导入jar::和配置的jar完全相同

13.2 在核心配置文件中通过context标签指定bean所在的包

<!-- context:component-scan 用于要指定要扫描的包::带注解的类所在的包 -->
<context:component-scan base-package="com.zhiyou100.test03"/>

13.3 创建实体类

package com.zhiyou100.test03;

import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;


/*
 * 注解1:创建bean的注解
 * @Controller::给控制层添加的注解
 * @Service::::给业务层添加的注解
 * @Repository::给持久层添加的注解
 * @Component::不属于某一层/不明确那一层的类添加的注解
 * */
@Component("tea1")//参数用于指定bean的id::如果不指定::bean的id为类名首字母小写
@Scope("singleton")//注解3:@Scope指定bean的作用域:singleton、prototype、request、session、global-session
@Lazy  //注解4:@Lazy指定懒加载
public class Teacher implements Serializable{
	@Value("1001")//注解2:@Value注解用于给属性赋值::可以加载属性上 也可以加在set方法上
	private Integer tid;
	@Value("韩梅梅")
	private String tname;
	
	private String tsex;
	//@Autowired  //注解6:@Autowired 自动装配
	@Resource  //等价于@Autowired 自动装配
	private School school;
	public School getSchool() {
		return school;
	}
	public void setSchool(School school) {
		this.school = school;
	}
	{
		System.out.println("构造代码块::"+this.hashCode());
	}
	public Integer getTid() {
		return tid;
	}
	public void setTid(Integer tid) {
		this.tid = tid;
	}
	public String getTname() {
		return tname;
	}
	public void setTname(String tname) {
		this.tname = tname;
	}
	public String getTsex() {
		return tsex;
	}
	@Value("女")
	public void setTsex(String tsex) {
		this.tsex = tsex;
	}

	
	@Override
	public String toString() {
		return "Teacher [tid=" + tid + ", tname=" + tname + ", tsex=" + tsex + ", school=" + school + "]";
	}
	public Teacher(Integer tid, String tname, String tsex) {
		super();
		this.tid = tid;
		this.tname = tname;
		this.tsex = tsex;
	}
	public Teacher() {
		super();
	}
	@PostConstruct  //注解5:@PostConstruct用于指定初始化方法
	public void methodInit(){
		System.out.println("初始化方法:::public void methodInit()");
	}
	@PreDestroy  //注解5:@PreDestroy用于指定销毁方法
	public void methodDestroy(){
		System.out.println("销毁方法:::public void methodDestroy()");
	}
}

14 模拟springioc

14.1 创建java项目

14.2 创建实体类

public class Student   implements Serializable{
	{
		System.out.println("构造代码块");
	}
	private Integer sid;
	private String sname;
	private Integer sage;
	private Boolean sdy;
	private Float score;
	private Teacher teacher;
    ...
}
public class Teacher implements Serializable{
	private Integer tid;
	private String tname;
	private String tsex;
    ...
}

14.3 创建核心配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<bean id="stu1" class="com.zhiyou100.test01.Student"> 
	     <property name="sid" value="1001"/>
	     <property name="sname" value="韩梅梅"/>
	     <property name="sage" value="19"/>
	     <property name="sdy" value="true"/>
	     <property name="score" value="11.6"/>
	</bean>
	<bean id="stu2" class="com.zhiyou100.test01.Student"> 
	     <constructor-arg name="sid" value="1002"/>
	     <constructor-arg name="sname" value="韩寒"/>
	     <constructor-arg name="sage" value="19"/>
	     <constructor-arg name="sdy" value="false"/>
	     <constructor-arg name="score" value="33.5"/>
	</bean>
	<bean id="stu3" class="com.zhiyou100.test01.Student"> 
	     <property name="sid" value="1001"/>
	     <property name="sname" value="韩梅梅"/>
	     <property name="sage" value="19"/>
	     <property name="sdy" value="true"/>
	     <property name="score" value="11.6"/>
	     <property name="teacher" ref="tea1"/>
	</bean>
	<bean id="tea1" class="com.zhiyou100.test01.Teacher" >
	    <property name="tid" value="1002"/>
	    <property name="tname" value="高老师"/>
	    <property name="tsex" value=""/>
	</bean>
</beans>

14.4 创建类模拟ClassPathXmlApplicationContext

方法:1 构造方法::加载核心配置文件
方法:2 getBean方法:根据bean的id获取对象
方法:3 close方法:释放资源销毁对象
package com.zhiyou100.test01;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class MyClassPathXmlApplicationContext {
	private Map<String, Object> mapBeans=new HashMap<String, Object>();
	private InputStream in;
	private Document doc;
	public MyClassPathXmlApplicationContext(String fileName){
		try {
			in=new FileInputStream(new File("src/"+fileName));
			doc=Utils.xml2Doc(in);
			//读取xml中所有的bean标签 创建对象
			init();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} 
		
	}
	private void init()throws Exception{
		//获取所有的bean标签
		NodeList beans=doc.getElementsByTagName("bean");
		//遍历
		for (int i = 0; i < beans.getLength(); i++) {
			Element beanEle=(Element)beans.item(i);
			//获取baen标签的id属性
			String id=beanEle.getAttribute("id");
			//获取baen标签的class属性
			String className=beanEle.getAttribute("class");
			//创建对象
			Class cla=Class.forName(className);
			Object obj=null;
			//判断当前bean标签下是否有constructor-arg子标签
			NodeList conZiList=beanEle.getElementsByTagName("constructor-arg");
			if(conZiList==null||conZiList.getLength()==0){
				obj=cla.newInstance();
				//获取所有的property子标签
				NodeList proZiList=beanEle.getElementsByTagName("property");
				//遍历property子标签
				for (int j = 0; j < proZiList.getLength(); j++) {
					Element proEle=(Element)proZiList.item(j);
					//获取name和value属性
					String name=proEle.getAttribute("name");
					String value=proEle.getAttribute("value");
					//获取字段对象
					Field field=cla.getDeclaredField(name);
					field.setAccessible(true);
					if(value!=null&&!value.isEmpty()){
						field.set(obj, Utils.changeType(value, field.getType()));
					}else{//赋值是通过ref
						String ref=proEle.getAttribute("ref");
						field.set(obj, mapBeans.get(ref));
					}
				}
			}else{
				//定义一个数组装构造方法的参数类型
				Class[] argsTypes=new Class[conZiList.getLength()];//记录构造方法的参数列表的类型
				Field[] fieldArr=new Field[conZiList.getLength()];//记录构造方法的参数列表属性
				String[] valueStrArr=new String[conZiList.getLength()];//记录构造方法的参数列表的字符串值
				Object[] valueObjArr=new Object[conZiList.getLength()];//记录构造方法的参数列表的值
				//遍历所有的constructor-arg子标签
				for (int j = 0; j <conZiList.getLength(); j++) {
					//获取constructor-arg子标签
					Element conZi=(Element)conZiList.item(j);
					//获取其name属性和value属性
					fieldArr[j]=cla.getDeclaredField(conZi.getAttribute("name"));
					valueStrArr[j]=conZi.getAttribute("value");
					valueObjArr[j]=Utils.changeType(valueStrArr[j], fieldArr[j].getType());
					argsTypes[j]=fieldArr[j].getType();
				}
				//通过构造方法给属性赋值的
				Constructor constructor=cla.getDeclaredConstructor(argsTypes);
				constructor.setAccessible(true);
				obj=constructor.newInstance(valueObjArr);
			}
			mapBeans.put(id, obj);
		}
	}
	public void close(){
		try {
			in.close();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	public Object getBean(String name){return mapBeans.get(name);}

}

14.5 测试

//1 创建springcontext对象 加载核心配置文件
MyClassPathXmlApplicationContext context=
    new MyClassPathXmlApplicationContext("com/zhiyou100/test01/spring_config.xml");
//	    //2 获取bean对象
Student s11=(Student)context.getBean("stu3");
System.out.println(s11);
//3 关闭容器
context.close();

image-20221226101311817

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值