一、对IOC的基本认识
- 简言之:控制反转 —依赖注入
- 说到IOC,首先会想到一个容器。(Hashtable)
- IOC意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
- 传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IOC是有专门一个容器来创建这些对象,即由IOC容器来控制对象的创建以及外部资源获取。
二、 代码实现
- 类 : User.java
package com.icss.biz;
public class User {
private String name;
private String pwd;
@MyAnnocation
private UserServer userServer;
public String getName() {
return name;
}
public String getPwd() {
return pwd;
}
public void run()
{
System.out.println("........");
userServer.show();
}
}
- 类 : UserController.java
package com.icss.biz;
public class UserController {
}
- 类 : UserDao.java
package com.icss.biz;
public class UserDao {
}
- 类 : UserServer.java
package com.icss.biz;
public class UserServer {
public void show()
{
System.out.println("这是userServer");
}
}
- 类 : MyAnnocation.java(注解)
package com.icss.biz;
import static java.lang.annotation.ElementType.FIELD;
import staticjava.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.Retention;
import static java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(FIELD)
public @interface MyAnnocation {
}
- 类 : AppliactionContext.java
package com.icss.biz;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.util.Hashtable;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class ApplicationContext {
// IOC 控制反转==DI 依赖注入
Hashtable<String, Object> h = new Hashtable<>();
public void init(String file)
{
try {
DocumentBuilder db= DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = db.parse(new FileInputStream(file));
Element node =doc.getDocumentElement();
NodeList nodeChild = node.getChildNodes();
for(int i=0;i<nodeChild.getLength();i++)
{
Node bean = nodeChild.item(i);
NamedNodeMap nodemap = bean.getAttributes();
if(nodemap!=null&&nodemap.getLength()>0)
{
Node clazz = nodemap.getNamedItem("class");
Node id = nodemap.getNamedItem("id");
if(clazz!=null&&id!=null)
{
String cl = clazz.getNodeValue();
String ci = id.getNodeValue();
System.out.println(cl+","+ci);
Object object = Class.forName(cl).newInstance();
h.put(ci, object);
}
}
}
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Object getobject(String id) throws IllegalArgumentException, IllegalAccessException
{
Object object =h.get(id);
Field[] fields = object.getClass().getDeclaredFields();
for(Field field :fields)
{
if(field.isAnnotationPresent(MyAnnocation.class))
{
field.setAccessible(true);
field.set(object,h.get(field.getName()));
}
}
return object;
}
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
ApplicationContext applicationContext = new ApplicationContext();
String file = ApplicationContext.class.getResource("/").getPath()+"/applicationContext.xml";
applicationContext.init(file);
User user = (User) applicationContext.getobject("user");
user.run();
}
}
7,xml文件 :applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 定义自己的xml格式 -->
<applicationcontext>
<bean id ="user" class="com.icss.biz.User"></bean>
<bean id ="userServer" class="com.icss.biz.UserServer"></bean>
<bean id ="userDao" class="com.icss.biz.UserDao"></bean>
<bean id ="userController" class="com.icss.biz.UserController"></bean>
</applicationcontext>
三、main运行结果
com.icss.biz.User,user
com.icss.biz.UserServer,userServer
com.icss.biz.UserDao,userDao
com.icss.biz.UserController,userController
........
这是userServer
四、总结
所以控制反转IOC(Inversion of Control)是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方,比如转移交给了IOC容器,它就是一个专门用来创建对象的工厂,你要什么对象,它就给你什么对象,有了 IOC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IOC容器了,通过IOC容器来建立它们之间的关系。
DI(依赖注入)其实就是IOC的另外一种说法,DI是由Martin Fowler 在2004年初的一篇论文中首次提出的。他总结道:控制的什么被反转了?就是获得依赖对象的方式反转了。