SpringIoc
- 控制反转:将对象创建工作交给spring容器去做,没有spring之前都是程序员new对象,这就是控制反转
- 优点:降低耦合
模拟
- 目标:处理service业务
- 这里会用到Dom4j去解析xml配置文件,中间有些方法不了解没有关系,把握大体思路,主要是为了理解是spring容器是怎么创建对象的。
- 实体类MageBean:表示从xml文件解析出来的bean,存储bean的配置信息
package com.ysjt.bean;
/**
* 存放配置信息
*/
public class MageBean {
private String id;
private String clazz;
public MageBean() {
}
public MageBean(String id, String clazz) {
this.id = id;
this.clazz = clazz;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
}
2.业务类HelloService:简单的模拟业务,打印一句话即可
package com.ysjt.service;
public class HelloService {
public void printHello(){
System.out.println("Hello spring");
}
}
3.application.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean class="com.ysjt.service.HelloService" id="helloService"></bean>
</beans>
4.BeanFactory接口:模拟spring中的BeanFactory
package com.ysjt.bean;
/**
* 模拟spring的BeanFactory类
*/
public interface BeanFactory {
Object getBean(String id);
}
5.MageApplicationContext类:对xml配置文件进行解析,创建bean对象
package com.ysjt.bean;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.util.CollectionUtils;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 模拟spring的ClassPathXmlApplicationContext类
*/
public class MageApplicationContext implements BeanFactory {
//配置文件路径
private String configLocation;
//存储配置文件信息
List<MageBean> mageBeanList = new ArrayList<>();
//存储bean对象集合
Map<String,Object> beans = new HashMap<>();
public MageApplicationContext() {
}
//容器一启动就加载配置文件,创建好bean对象
public MageApplicationContext(String configLocation) {
this.configLocation = configLocation;
//解析配置文件
parseConfigLocation();
//生成bean对象
generatorBean();
}
//解析配置文件
private void parseConfigLocation(){
//获取项目配置文件
URL url = this.getClass().getClassLoader().getResource(configLocation);
if(url == null){
System.out.println("资源不存在");
return;
}
//解析配置文件
SAXReader saxReader = new SAXReader();
try{
//读取xml文件,获取document对象
Document document = saxReader.read(url);
List<Element> elements = document.selectNodes("/beans/bean");
//循环遍历将配置文件信息添加到mageBeanList集合
elements.forEach(e->{
String id = e.attributeValue("id");
String clazz = e.attributeValue("class");
//测试解析是否成功
// System.out.println(id+":"+clazz);
MageBean mageBean = new MageBean(id,clazz);
mageBeanList.add(mageBean);
});
}catch (DocumentException e){
e.printStackTrace();
}
}
//生成bean对象
private void generatorBean(){
//配置文件是否有bean对象待创建
if(CollectionUtils.isEmpty(mageBeanList))
return;
mageBeanList.forEach(bean->{
try{
//反射创建对象,
beans.put(bean.getId(),Class.forName(bean.getClazz()).newInstance());
}catch (Exception e){
e.printStackTrace();
}
});
}
@Override
public Object getBean(String id) {
return beans.get(id);
}
}
6.测试
package com.ysjt.test;
import com.ysjt.bean.BeanFactory;
import com.ysjt.bean.MageApplicationContext;
import com.ysjt.service.HelloService;
public class MockContainerTest {
public static void main(String[] args) {
BeanFactory context = new MageApplicationContext("application.xml");
HelloService helloService = (HelloService) context.getBean("helloService");
helloService.printHello();
}
}
模拟环境
依赖jar:
dom4j-1.6.1.jar
jaxen-1.1.6.jar
spring-aop-5.2.1.RELEASE.jar
spring-beans-5.2.1.RELEASE.jar
spring-context-5.2.1.RELEASE.jar
spring-context-support-5.2.1.RELEASE.jar
spring-core-5.2.1.RELEASE.jar
spring-expression-5.2.1.RELEASE.jar
spring-jcl-5.2.1.RELEASE.jar