Welcome 微信登录

首页 / 操作系统 / Linux / Spring IOC的简单实现

IoC则是一种 软件设计模式,简单来说Spring通过工厂+反射来实现IoC。原理简单说明:
其实就是通过解析xml文件,通过反射创建出我们所需要的bean,再将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便我们获得这bean。
通俗来讲就如同婚姻介绍所,只需要告诉它找个什么样的女朋友,然后婚介就会按照我们的要求,提供一个mm,如果婚介给我们的人选不符合要求,我们就会抛出异常。简单实现:
1.需要引用maven依赖: <dependency><groupId>org.jdom</groupId><artifactId>jdom</artifactId><version>1.1.3</version></dependency>2.beans.xml<?xml version="1.0" encoding="UTF-8"?><beans><bean id="user" class="com.example.domain.User" /><bean id="userDAO" class="com.example.dao.impl.UserDAOImpl" /><bean id="userService" class="com.example.service.UserService"><property name="userDAO" bean="userDAO" /></bean></beans>3.BeanFactorypackage com.example.ioc;public interface BeanFactory {Object getBean(String name);}4.ClassPathXmlApplicationContext:读取xml文件内容,并创建对象及对象关系(使用setter方式)package com.example.ioc;import org.jdom.Document;import org.jdom.Element;import org.jdom.input.SAXBuilder;import java.lang.reflect.Method;import java.util.HashMap;import java.util.List;import java.util.Map;public class ClassPathXmlApplicationContext implements BeanFactory {private Map<String, Object> beans = new HashMap<String, Object>();public ClassPathXmlApplicationContext() throws Exception {SAXBuilder sb = new SAXBuilder();// 构造文档对象Document doc = sb.build(ClassPathXmlApplicationContext.class.getClassLoader().getResourceAsStream("beans.xml"));// 获取根元素Element root = doc.getRootElement();// 取到根元素所有元素List list = root.getChildren();setBeans(list);}//设置Beanprivate void setBeans(List list) throws Exception {for (int i = 0; i < list.size(); i++) {Element element = (Element) list.get(i);String id = element.getAttributeValue("id");//取得class子元素String clzss = element.getAttributeValue("class");//通过反射进行实例化Object o = Class.forName(clzss).newInstance();beans.put(id, o);setProperty(element, o);}}//获取property进行依赖注入private void setProperty(Element element, Object o) throws Exception {for (Element property : (List<Element>) element.getChildren("property")) {String name = property.getAttributeValue("name");String bean = property.getAttributeValue("bean");//从beans.xml中根据id取到类的对象Object beanObj = this.getBean(bean);System.out.println(beanObj);//com.example.dao.impl.UserDAOImpl@2f4d3709//组成setXXX方法名String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);// 反射机制对方法进行调用,将对象在加载bean时就注入到环境上下文中Method m = o.getClass().getMethod(methodName, beanObj.getClass().getInterfaces()[0]);m.invoke(o, beanObj);}}@Overridepublic Object getBean(String name) {return beans.get(name);}}以上为核心代码,当然在实际情况中,这一块要复杂的多, 例如:可以一个bean引用另一个bean,还可以有多个配置文件、通过多种方式载入配置文件等等,不过原理还是采用Java的反射机制。实现的效果为:
Service service=(Service)beans.get("userService");
Dao dao = (Dao)beans.get("userDAO");
//依赖注入,Service实现依赖dao的实现
service.setDao(dao);5.User:实体类package com.example.domain;public class User {private String userName;private String password;/** * @return the userName */public String getUserName() {return userName;}/** * @param userName the userName to set */public void setUserName(String userName) {this.userName = userName;}/** * @return the password */public String getPassword() {return password;}/** * @param password the password to set */public void setPassword(String password) {this.password = password;}public String toString() {StringBuffer sb = new StringBuffer();sb.append(this.userName);sb.append(this.password);return sb.toString();}}6.UserDAOpackage com.example.dao;import com.example.domain.User;public interface UserDAO {void save(User u);void delete();}7.UserDAOImplpackage com.example.dao.impl;import com.example.dao.UserDAO;import com.example.domain.User;public class UserDAOImpl implements UserDAO {@Overridepublic void save(User u) {System.out.println("User:" + u.toString());}@Overridepublic void delete() {System.out.println("delete User");}}8.UserServicepackage com.example.service;import com.example.dao.UserDAO;import com.example.domain.User;public class UserService {private UserDAO userDAO;public void addUser(User u) {this.userDAO.save(u);}/** * @return the userDAO */public UserDAO getUserDAO() {return userDAO;}/** * @param userDAO the userDAO to set */public void setUserDAO(UserDAO userDAO) {this.userDAO = userDAO;}}9.测试:package com.example.ioc;import com.example.domain.User;import com.example.service.UserService;public class RunIoc {public static void main(String[] args) throws Exception {BeanFactory factory = new ClassPathXmlApplicationContext();//通过工厂直接获取UserService userService = (UserService) factory.getBean("userService");//其实User也可以从工厂中获得User u = (User) factory.getBean("user");//User u = new User();u.setUserName("tom");u.setPassword("123456");userService.addUser(u);//打印结果tom123456}}小结上文仅仅是简单地模拟了spring的IOC的实现,虽然只是完成了spring中依赖注入的一小部分,但还是很好地展现了Java反射机制在spring中的应用本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-01/139902.htm