一、IOC基本概念
IoC(Inversion of Control),直观地讲,就是对象创建或查找对象依赖的控制权由应用代码转到了外部容器,控制权的转移是所谓反转。使用Ioc,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。
二、IOC场景举例
丽萨已经老大不小了,一直没有男朋友,看着别人恩恩爱爱的,也不禁想找个BoyFriend。摆在她面前的有3种方案:主动“邂逅” Or 同事介绍 或者父母包办。她会选择哪种呢?
第二方案,同事介绍 或者父母包办,
虽然在现实生活中我们都希望与自己的另一半来场完美的邂逅,但在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
本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多