IoC(Inversion of Control),直观地讲,就是对象创建或查找对象依赖的控制权由应用代码转到了外部容器,控制权的转移是所谓反转。使用Ioc,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。
丽萨已经老大不小了,一直没有男朋友,看着别人恩恩爱爱的,也不禁想找个BoyFriend。摆在她面前的有3种方案:主动“邂逅” Or 同事介绍 或者父母包办。她会选择哪种呢?
第二方案,同事介绍 或者父母包办,
虽然在现实生活中我们都希望与自己的另一半来场完美的邂逅,但在Spring世界里,跟丽萨一样,选择的却是父母包办,它就是控制反转,而这里具有控制力的父母,就是Spring所谓的容器概念。
代码结构如下图所示
定义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