Spring之IOC配置原理

前言:今天不说spring boot,来探讨一下spring的配置文件。spring的核心就是IOC和AOP,下面说的就是IOC。

IOC:术名控制反转,第一次听这个肯定一头雾水,没关系,下面就来认识一下这个陌生面孔。创建对象的方式一般分为两种,一种是平时用的最多,直接new对象,还有一种是利用java提供的反射机制创建对象,IOC的底层就是反射。

1、普通的创建对象方式

PersonServiceOfNormal类为例

public class PersonServiceOfNormal {
	public PersonServiceOfNormal() {
		System.out.println("我是new出来的对象,被初始化了。。。");
	}
}

Test方法 

@Test
void testPersonServiceOfNormal() {
	PersonServiceOfNormal person = new PersonServiceOfNormal();
}

 执行结果如下,对象被初始化,没问题

2、反射创建出来的对象

PersonServiceOfReflect类为例

public class PersonServiceOfReflect {
	
	public PersonServiceOfReflect() {
		System.out.println("我是反射出来的对象,被初始化了。。。");
	}

}

Test类

@Test
	void testPersonServiceOfReflect() throws Exception {
		Class<?> classPerson = Class.forName("cn.zdxh.service.PersonServiceOfReflect");
		PersonServiceOfReflect person=(PersonServiceOfReflect) classPerson.newInstance();
	}

通过Class类的静态方法forName传入类的名称获得对应的class类,再通过newInstance方法构造对象,这就是发射的构造对象方法

执行结果,对象被成功初始化

3、spring的IOC

说得通俗点,spring的IOC就是通过解析xml文件的配置信息创建对象以及设置其他属性。

为什么仅仅只配置一个类名,spring框架就可以帮我们创建对象并管理对象?(这里以bean节点为例)

通过查看源码,DefaultBeanDefinitionDocumentReader类中有个parseBeanDefinitions方法,其作用就是解析配置的节点,再用解析出来的节点属性值来创建对象以及做其他的操作,对象的生命周期则是通过监听容器来管理的

以下的属性被解析(部分)

 根据这个属性,自己定义一个xml文件,然后解析文件,再创建对象

首先,在eclipse中配置一个tomcat可读取访问的系统路径

 再把自定义的配置文件放到该文件夹下,节点内容随便怎样写,只要按照一定的方式解析就行

<?xml version="1.0" encoding="UTF-8"?>
<configure>
<beans>
	<bean value="cn.zdxh.service.PersonServiceOfXmlReflect"/>
	<bean value="cn.zdxh.service.PersonServiceOfReflect"/>
</beans>
</configure>


新添一个PersonServiceOfXmlReflect类作为演示

public class PersonServiceOfXmlReflect {
	public PersonServiceOfXmlReflect() {
		System.out.println("我是通过解析xml反射出来的对象,被初始化了。。。");
	}
}

示例采用dom4j解析xml文件,相关的jar包在网上搜索下载即可

Test类

        @Test
	void testPersonServiceOfXmlReflect() throws Exception {
		
		SAXReader saxReader = new SAXReader();
		//读取指定文件夹的xml文件
		Document document = saxReader.read(new File("E:/upload/picture/configure.xml"));
		Element element = document.getRootElement();

		//获得beans节点下的所有的bean子节点,根节点不读取
		List<Element> listBeans=element.element("beans").elements("bean");
		if(listBeans!=null && listBeans.size()>0) {
			//递归遍历父节点下的所有子节点
		     for(Element e : listBeans){
		    	//获得所有的bean标签里面的值
		     		Class<?> classPerson = Class.forName(e.attributeValue("value"));
		     		//反射创建所有的对象
		     		Object newInstance = classPerson.newInstance();
		     }
		}
	}

执行结果,两个配置的类被成功初始化

 总结:IOC的大概设计思想就是这样,无论是新秀ssm框架还是旧将ssh框架,只要把握好设计思想,学起来就没那么辛苦。最后一句,java大法好!

猜你喜欢

转载自blog.csdn.net/weixin_38802061/article/details/83414629