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