Spring IOC的简单实现(附demo)

简单的说,Spring就是通过工厂+反射将我们的bean放到它的容器中的,当我们想用某个bean的时候,只需要调用getBean("beanID")方法即可。

原理简单说明:

Spring容器的原理,其实就是通过解析xml文件,通过反射创建出我们所需要的bean,再将这些bean挨个放到集合中,然后对外提供一个getBean()方法,以便我们获得这bean。

下面我们来简单实现一个demo

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="user" class="com.yyb.model.User" />
    <bean id="userDAO" class="com.yyb.dao.impl.UserDAOImpl" />
    <bean id="userService" class="com.yyb.service.UserService">
        <property name="userDAO" bean="userDAO" />
    </bean>
</beans> 

BeanFactory

public interface BeanFactory {

	 Object getBean(String name);
}

ClassPathXmlApplicationContext:读取xml文件内容,并创建对象及对象关系(使用setter方式)

package com.yyb.spring;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
public class ClassPathXmlApplicationContext implements BeanFactory
{
	private Map<String, Object> beans = new HashMap<String, Object>();
	public ClassPathXmlApplicationContext() throws JDOMException, IOException,
			InstantiationException, IllegalAccessException,
			ClassNotFoundException, SecurityException, NoSuchMethodException,
			IllegalArgumentException, InvocationTargetException
	{
		SAXBuilder sb = new SAXBuilder();
		// 构造文档对象
		Document doc = sb.build(ClassPathXmlApplicationContext.class
				.getClassLoader().getResourceAsStream("beans.xml"));
		// 获取根元素
		Element root = doc.getRootElement();
		// 取到根元素所有元素
		List list = root.getChildren();

		for (int i = 0; i < list.size(); i++)
		{
			Element element = (Element) list.get(i);
			// 取id子元素
			String beanid = element.getAttributeValue("id");
			// 取class子元素
			String clzss = element.getAttributeValue("class");
			// 实例化
			Object o = Class.forName(clzss).newInstance();
			// 将所有bean放入map中
			beans.put(beanid, o);
			// 获取property 进行依赖注入
			for (Element propertyElement : (List<Element>) element
					.getChildren("property"))
			{
				String name = propertyElement.getAttributeValue("name");
				System.out.println(name);//userDAO
				String bean = propertyElement.getAttributeValue("bean");
				System.out.println(bean);//userDAO
				// 从beans.xml中根据id取到类的对象
				//Object beanObj = this.getBean(name);
				// 从beans.xml中根据id取到类的对象
				Object beanObj = this.getBean(bean);
				System.out.println(beanObj);//[email protected]
				// 形成setXXX方法名
				String methodName = "set" + name.substring(0, 1).toUpperCase()
						+ name.substring(1);
				System.out.println(name.substring(0, 1).toUpperCase());//U
				System.out.println(name.substring(1));//serDAO
				System.out.println(methodName);//setUserDAO

				// 反射机制对方法进行调用,将对象在加载bean时就注入到环境上下文中
				Method m = o.getClass().getMethod(methodName,
						beanObj.getClass().getInterfaces()[0]);
				System.out.println(o.getClass());//class com.yyb.service.UserService
				System.out.println(beanObj.getClass().getInterfaces()[0]);//interface com.yyb.dao.UserDAO
				System.out.println(m);//public void com.yyb.service.UserService.setUserDAO(com.yyb.dao.UserDAO)
				// 执行注入,相当于执行了一个setXXX(args..)的方法
				m.invoke(o, beanObj);
			}
		}
	}
	@Override
	public Object getBean(String name)
	{
		return beans.get(name);
	}
}

对于以上这段代码实现的效果为:

Service service=(Service)beans.get("userService");

Dao dao = (Dao)beans.get("userDAO");

//依赖注入,Service实现依赖dao的实现

service.setDao(dao);

User:实体类

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();
    }
}

UserDAO

public interface UserDAO {
	 void save(User u);
	 void delete();
}

UserDAOImpl

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");  

	    }
}

UserService

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;
    }
}

下面我们来简单测试一下实现的效果:

Client

public class client {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, JDOMException, IOException {
	BeanFactory factory = new ClassPathXmlApplicationContext();
	//通过工厂直接获取
        UserService userService = (UserService) factory.getBean("userService");
        //其实User也可以从工厂中获得
        User u=(User)factory.getBean("user");
        //User u = new User();
        u.setUserName("yyb");
        u.setPassword("1234");
        userService.addUser(u);//打印结果yyb1234
	}

}

当然以上我们是通过setter方法注入,还可以使用构造器注入,也就是在建立对象的时候建立关系(即在UserService的构造函数中添加对userDAO的赋值操作)

总结:

以上通过IOC的一个简要实现实例,模拟了Spring中IOC的实现,虽然只是完成了Spring中依赖注入的一小部分工作,但是很好的展现了Java反射机制在Spring中的应用,能使我们能更好的从原理上了解IOC的实现,也能为我们实现自己的Spring框架提供了方案。

Spring IOC实现原理demo:IOC

时间: 2024-10-29 12:03:15

Spring IOC的简单实现(附demo)的相关文章

Spring IOC 的简单使用

Spring IOC (Inversion Of Control反转控制容器 一.对于IOC容器的简单理解 在java开发中将程序中的对象交给容器管理,而不是在对象的内部管理. 那么两个简单的问题去分析理解IOC容器 1.为什么叫反转: IOC容器实现了将对象的管理由对象内部直接管理(比如在一个类的main方法中new了一个String对象)转换成在容器中被动的被注入,创建.把这种对对象管理方式的改变称为反转. 2.控制了什么: IOC容器控制了外部资源的统一获取(不仅仅包括对象,还有其他的文件

基于socket的客户端和服务端聊天简单使用 附Demo

功能使用 服务端 分离一个不停接受客户端请求的线程 接受不客户端请求的线程中,再分离就收消息的线程 几大对象分别是 IPEndPoint IP终结点 服务端Socket,绑定终结点Bind,启动监听Listen(100) 100代表的监听请求队列的长度 接受请求的客户端Socket,接受消息 Receive 接受的字节与文本间的互转 客户端 只有一个分离接受服务端发送消息的线程 几大对象 客户端Socket 客户端连接Connect 客户端发送 客户端接受 接受的字节与文本间的互转 附Demo下

C#开发微信公众平台-就这么简单(附Demo)

写在前面 阅读目录: 服务号和订阅号 URL配置 创建菜单 查询.删除菜单 接受消息 发送消息(图文.菜单事件响应) 示例Demo下载 后记 最近公司在做微信开发,其实就是接口开发,网上找了很多资料,当然园友也写了很多教程,但都是理论说了一大堆,实用指导或代码很少.如果你自己仔细研究下,其实就那么点东西,C#实现起来也很简单,原本不想写这篇文章的,但是本人当时摸索走了很多弯路,这边总结下,希望初次接触微信公众平台的朋友别像当时的我一样. 自己动手,丰衣足食. 服务号和订阅号 服务号是公司申请的微

EventBus简单应用和简单分析(附demo)

貌似最近EventBus挺火,自己找了找资料,然后看了看,写了个简单demo.供大家参考. EventBus项目中没有用到,我也是自己看一些资料,所以东西相对简单,见谅.一些高级功能,也只能靠大家自行摸索了. 一:首先说一下我觉得EventBus几个重要的点吧. 1.这个类似广播需要你将EventBus register和unregister 一般在onCreate()中注册,在onDestory()中注册.为什么要注册? 当你register()之后,他会遍历你的.class文件,找到几个重要

Spring容器的简单实现(IOC原理)

引言:容器是什么?什么是容器?Spring容器又是啥东西?我给Spring容器一个对象名字,为啥能给我创建一个对象呢? 一.容器是装东西的,就像你家的水缸,你吃饭的碗等等. java中能作为容器的有很多,例如Map,List,数组.....还有好多 二.Spring 容器的核心就是一个Map集合(可能不是很准确,见谅!) Map<String, Object> 这个容器里根据key-value存放了好多键值对.假如你给一个String的key,就能获得相应的Object的对象,各位大佬,对Sp

Spring IOC 方式结合TESTGN测试用例,测试简单java的命令模式

java命令模式: 可以命令("请求")封装成一个对象,一个命令对象通过在特定的接收着上绑定一组动作来封装一个请求.命令对象直接把执行动作和接收者包进对象中,只对外暴露出执行方法的的接口,从而简单的达到动作的请求者和动作的执行者解耦的目的. 下面用一个简单的实例测试简单的命令模式,同时采用spring ioc的方式+testNG的测试方式,实现遥控器的遥控开灯的命令模式实现和测试. 1.建立命令接口,包含执行方法,命令对象必须要实现的,执行方法就是暴露的接口方法,提供于接收者调用. p

【spring】1.spring ioc原理和demo

我们先做一个简单的spring例子. 面向接口编程,我们先来定接口 IHelloWorld package com.services; public interface IHelloWorld { public void sayHello(); } 写一个实现类,并且声明一个String属性,提供set方法注入 package com.services.impl; import com.services.IHelloWorld; public class HelloWorld implement

简单的Spring Ioc

控制反转(Inversion of Control,Ioc),也被称为依赖注入(Dependency Injection,DI),是面向对象的一种设计理念,用来降低程序代码之间的耦合度. 首先要考虑什么是依赖.依赖,在代码中一般是指通过局部变量.方法参数.返回值等建立的对于其他对象的调用关系.例如,A类的方法中,实例化了B类的对象并调用其方法已完成特定的功能,我们就说A类依赖于B类 ---------------------------正文---------------------------

Spring之AOP简单demo

1.添加JAR包,出了Spring自身的Jar包还要一些依赖的JAR包,不然会报ClassNotFound. Student.java package com.lubby.bean; import org.springframework.stereotype.Component; @Component("student") public class Student { private String id; private String name; public Student() {