IOC 控制反转 == DI 依赖注入,我对这个概念的理解就是自己不new一个对象,而是通过ioc容器来实现一个对象
实现ioc首先先配置xml文件 一般命名为applicationContext.xml,并放在src名录下
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 定义自己的XML格式 -->
<beans>
<!-- id为唯一标识 -->
<bean id="user" class="com.icss.ui.User"></bean>
<bean id="userDao" class="com.icss.ui.UserDao"></bean>
<bean id="userService" class="com.icss.ui.UserService"></bean>
<bean id="userController" class="com.icss.ui.UserController">
<ref id="userService"></ref>
</bean>
</beans>
我采用注解的方式来实现ioc 所以写个注解
AutoWired
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({FIELD})
public @interface AutoWired {
}
通过ioc实现一个user对象 所以写个user类
public class User {
private String userName;
private String userPwd;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
}
UserService
public class UserService {
public User getUser() {
System.out.println("调用");
return new User();
}
}
通过ioc实现一个UserController对象 所以写个UserController类
UserController
public class UserController {
@AutoWired
private UserService userService;
public void login() {
//便于观察是否创建对象
userService.getUser();
}
}
下面写主程序
ApplicationContext
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Hashtable;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class ApplicationContext {
// IOC 控制反转 == DI 依赖注入
// 定义IOC容器(Hashtable)对象
private Hashtable<String, Object> container = new <String, Object>Hashtable();
public void xmlInit(String fileName) throws FileNotFoundException, SAXException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
try {
//DocumentBuilderFactory用来解析xml文件
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
// 解析传入的xml文件
Document doc = db.parse(new FileInputStream(fileName));
// 得到根节点
Node root = doc.getDocumentElement();
// 得到根节点的孩子节点
NodeList childList = root.getChildNodes();
for (int i = 0; i < childList.getLength(); i++) {
// 得到bean节点
Node childNode = childList.item(i);
// 得到节点属性
NamedNodeMap nodeAttributes = childNode.getAttributes();
//判断节点是否有属性值
if(nodeAttributes!=null&&nodeAttributes.getLength()>0) {
Node clazz = nodeAttributes.getNamedItem("class");
Node id = nodeAttributes.getNamedItem("id");
if(clazz!=null&id!=null) {
String className = clazz.getNodeValue();
String idName = id.getNodeValue();
System.out.println(className);
System.out.println(idName);
//依据配置文件实例化类对象存入容器
Object obj=Class.forName(className).newInstance();
// 存入容器
container.put(idName, obj);
}
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
}
public Object getBean(String id) throws IllegalArgumentException, IllegalAccessException {
Object obj =container.get(id);
//基于注解来实现依赖注入
Field[] fields = obj.getClass().getDeclaredFields();
for(Field field:fields) {
//用来识别被注释的类
if (field.isAnnotationPresent(AutoWired.class)) {
//给对象obj的属性赋值
field.setAccessible(true);
//就是依赖注入(核心实现)
field.set(obj, container.get(field.getName()));
}
}
return obj;
}
public static void main(String[] args) throws FileNotFoundException, SAXException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {
//解析XML文件
ApplicationContext applicationContext = new ApplicationContext();
String path="E:\\eclipse\\eclipse-workspace\\ioc\\src\\";
applicationContext.xmlInit(path + "applicationContext.xml");
//从容中获取对象:单例模式还是非单例模式
User user=(User) applicationContext.getBean("user");
//ioc的依赖注入
UserController userController =(UserController)applicationContext.getBean("userController");
userController.login();
}
}
结果
xml文件里的bean都被解析出来放进了ioc容器中
“调用”被打印出来说明userController被依赖注入
换句话说 userController不是自己new出来的 而是通过别人(ioc容器)创建出来的一个对象