博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
自己实现简单Spring Ioc
阅读量:5337 次
发布时间:2019-06-15

本文共 5317 字,大约阅读时间需要 17 分钟。

IoC则是一种 软件设计模式,简单来说Spring通过工厂+反射来实现IoC。

原理简单说明:

其实就是通过解析xml文件,通过反射创建出我们所需要的bean,再将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便我们获得这bean。
通俗来讲就如同婚姻介绍所,只需要告诉它找个什么样的女朋友,然后婚介就会按照我们的要求,提供一个mm,如果婚介给我们的人选不符合要求,我们就会抛出异常。

简单实现:


1.需要引用maven依赖:

org.jdom
jdom
1.1.3

2.beans.xml

3.BeanFactory

package 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
beans = new HashMap
(); 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); } //设置Bean private 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.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); } } @Override public 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.UserDAO

package com.example.dao;import com.example.domain.User;public interface UserDAO {    void save(User u);    void delete();}

7.UserDAOImpl

package com.example.dao.impl;import com.example.dao.UserDAO;import com.example.domain.User;public class UserDAOImpl implements UserDAO {    @Override    public void save(User u) {        System.out.println("User:" + u.toString());    }    @Override    public void delete() {        System.out.println("delete User");    }}

8.UserService

package 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中的应用

转载于:https://www.cnblogs.com/lspz/p/6244948.html

你可能感兴趣的文章
HDU 4358 Boring counting(莫队+DFS序+离散化)
查看>>
NBOJv2 1050 Just Go(线段树/树状数组区间更新单点查询)
查看>>
SCU 4438 Censor(哈希+模拟栈)
查看>>
在 Tomcat 中自定义 404 页面(简单配置)
查看>>
HDU-1298-T9
查看>>
U盘制作macOS Sierra的启动盘
查看>>
JAVA单例模式详解
查看>>
Kafka集群的安装和使用
查看>>
语言的转义字符及正则表达式的转义字符的表示
查看>>
C++_归并排序
查看>>
javascript初始笔记
查看>>
02.MySQL.存储引擎-事务-隔离级别-锁
查看>>
html的文字标记
查看>>
优先队列-优先级别
查看>>
jQuery实现,动态自动定位弹窗。JS分页,Ajax请求
查看>>
iis应用程序池 内存溢出错误 System.OutOfMemoryException
查看>>
2017.3.19 for
查看>>
MFC中的DLL、LIb文件的创建、使用
查看>>
LeetCode_Jump Game II
查看>>
无法将类型“int”隐式转换为“string”
查看>>