转载

自动动手实现Spring的IOC

一、IOC基本概念

IoC(Inversion of Control),直观地讲,就是对象创建或查找对象依赖的控制权由应用代码转到了外部容器,控制权的转移是所谓反转。使用Ioc,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。

二、IOC场景举例

丽萨已经老大不小了,一直没有男朋友,看着别人恩恩爱爱的,也不禁想找个BoyFriend。摆在她面前的有3种方案:主动“邂逅” Or 同事介绍 或者父母包办。她会选择哪种呢?

自动动手实现Spring的IOC 第二方案,同事介绍 或者父母包办,

虽然在现实生活中我们都希望与自己的另一半来场完美的邂逅,但在Spring世界里,跟丽萨一样,选择的却是父母包办,它就是控制反转,而这里具有控制力的父母,就是Spring所谓的容器概念。

三、IOC代码实现

代码结构如下图所示

定义POJO类

package org.springioc;
public class Student {

 private String name;
 private String add;
 
 public void selfIntroDuction(){
 System.out.println("我的姓名是 " + name + " 我来自 " + add);
 
 }
 
 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }

 public String getAdd() {
 return add;
 }

 public void setAdd(String add) {
 this.add = add;
 }
 
}

定义Service服务

package org.springioc;

public class StudentService {
 private Student student;

public Student getStudent() {
 return student;
}

public void setStudent(Student student) {
 this.student = student;
}
 
}

定义配置文件,将上述2个类信息写入进入

<?xml version="1.0" encoding="UTF-8"?>

<beans>
 <bean id="Student" class="org.springioc.Student">
 <property name="name" value="Hover"/>
 <property name="add" value="China"/>
 </bean>

 <bean id="StudentService" class="org.springioc.StudentService">
 <property ref="Student"/>
 </bean>
</beans>

定义ApplicationContext接口

package org.springioc;

public interface ApplicationContext {
 /**
 * 获取bean
 * @param string
 * @return
 */
 Object getBean(String string);

}

接口的实现类,加载配置文件,并且解析xml,将bean注入到map

package org.springioc;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

public class ClassPathXMLApplicationContext implements ApplicationContext{
 //文件加载
 private File file;
 //bean容器
 private ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<String, Object>();
 //构造函数
 public ClassPathXMLApplicationContext(String config_file) {
 URL url = this.getClass().getClassLoader().getResource(config_file);
 try {
 file = new File(url.toURI());
 XMLParsing();
 } catch (Exception e) {
 e.printStackTrace();
 }
 
 }
 /**
 * 解析xml,并且将bean 注册到map
 * @throws Exception
 */
 private void XMLParsing() throws Exception { 
 SAXBuilder builder = new SAXBuilder();
 Document doc = builder.build(file);
 XPath xpath = XPath.newInstance("//bean");
 List beans = xpath.selectNodes(doc);
 Iterator i = beans.iterator();
 while (i.hasNext()) {
 Element bean = (Element) i.next();
 String id = bean.getAttributeValue("id");
 String cls = bean.getAttributeValue("class");
 Object obj = Class.forName(cls).newInstance();
 Method[] method = obj.getClass().getDeclaredMethods();
 List<Element> list = bean.getChildren("property");
 for (Element el : list) {
 for (int n = 0; n < method.length; n++) {
 String name = method[n].getName();
 String temp = null;
 if (name.startsWith("set")) {
 temp = name.substring(3, name.length()).toLowerCase();
 if (el.getAttribute("name") != null) {
 if (temp.equals(el.getAttribute("name").getValue())) {
 method[n].invoke(obj, el.getAttribute("value").getValue());
 }
 } else {
 method[n].invoke(obj,map.get(el.getAttribute("ref").getValue()));
 }
 }
 }
 }
 map.put(id, obj);
 }
 }

 public Object getBean(String name) {
 return map.get(name);
 }

}

POM.xml配置文件

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <modelVersion>4.0.0</modelVersion>
 <parent>
 <groupId>cn.maxap</groupId>
 <artifactId>search-parent</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 </parent>
 <groupId>cn.maxap</groupId>
 <artifactId>springioc</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <name>springioc</name>
 <url>http://maven.apache.org</url>
 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>
 <dependencies>
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <version>3.8.1</version>
 <scope>test</scope>
 </dependency>
 <!-- https://mvnrepository.com/artifact/jdom/jdom -->
<dependency>
 <groupId>jdom</groupId>
 <artifactId>jdom</artifactId>
 <version>1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jaxen/jaxen -->
<dependency>
 <groupId>jaxen</groupId>
 <artifactId>jaxen</artifactId>
</dependency>

 
 </dependencies>
</project>

测试类

package org.springioc;

public class Test {
 public static void main(String[] args) {
 //加载资源文件,并且解析bean到map里面
 ApplicationContext context = new ClassPathXMLApplicationContext("application.xml");
 //获取bean
 StudentService stuServ = (StudentService) context.getBean("StudentService");
 //调用方法
 stuServ.getStudent().selfIntroDuction();
 }
 
}

输出结果

我的姓名是 Hover 我来自 China

项目代码已经上传到https://gitee.com/jxuasea/maxap/tree/master/springioc

自动动手实现Spring的IOC

原文  https://juejin.im/post/5af501735188256712789190
正文到此结束
Loading...