码迷,mamicode.com
首页 > 编程语言 > 详细

Spring IOC的简单实现

时间:2018-02-02 18:35:55      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:property   delete   内容   工作   method   doc   为我   sdn   void   

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

 

原理简单说明:

 

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

 

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

 

beans.xml

 

[html] view plain copy
 
 print?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans>    
  3.     <bean id="user" class="com.yyb.model.User" />    
  4.     <bean id="userDAO" class="com.yyb.dao.impl.UserDAOImpl" />    
  5.     <bean id="userService" class="com.yyb.service.UserService">    
  6.         <property name="userDAO" bean="userDAO" />    
  7.     </bean>    
  8. </beans>   

 

BeanFactory

 

[java] view plain copy
 
 print?
  1. public interface BeanFactory {  
  2.   
  3.      Object getBean(String name);    
  4. }  

 

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

 

[java] view plain copy
 
 print?
  1. package com.yyb.spring;  
  2. import java.io.IOException;  
  3. import java.lang.reflect.InvocationTargetException;  
  4. import java.lang.reflect.Method;  
  5. import java.util.HashMap;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8.   
  9. import org.jdom.Document;  
  10. import org.jdom.Element;  
  11. import org.jdom.JDOMException;  
  12. import org.jdom.input.SAXBuilder;  
  13. public class ClassPathXmlApplicationContext implements BeanFactory  
  14. {  
  15.     private Map<String, Object> beans = new HashMap<String, Object>();  
  16.     public ClassPathXmlApplicationContext() throws JDOMException, IOException,  
  17.             InstantiationException, IllegalAccessException,  
  18.             ClassNotFoundException, SecurityException, NoSuchMethodException,  
  19.             IllegalArgumentException, InvocationTargetException  
  20.     {  
  21.         SAXBuilder sb = new SAXBuilder();  
  22.         // 构造文档对象  
  23.         Document doc = sb.build(ClassPathXmlApplicationContext.class  
  24.                 .getClassLoader().getResourceAsStream("beans.xml"));  
  25.         // 获取根元素  
  26.         Element root = doc.getRootElement();  
  27.         // 取到根元素所有元素  
  28.         List list = root.getChildren();  
  29.           
  30.         for (int i = 0; i < list.size(); i++)  
  31.         {  
  32.             Element element = (Element) list.get(i);  
  33.             // 取id子元素  
  34.             String beanid = element.getAttributeValue("id");  
  35.             // 取class子元素  
  36.             String clzss = element.getAttributeValue("class");  
  37.             // 实例化  
  38.             Object o = Class.forName(clzss).newInstance();  
  39.             // 将所有bean放入map中  
  40.             beans.put(beanid, o);  
  41.             // 获取property 进行依赖注入  
  42.             for (Element propertyElement : (List<Element>) element  
  43.                     .getChildren("property"))  
  44.             {  
  45.                 String name = propertyElement.getAttributeValue("name");  
  46.                 System.out.println(name);//userDAO  
  47.                 String bean = propertyElement.getAttributeValue("bean");  
  48.                 System.out.println(bean);//userDAO  
  49.                 // 从beans.xml中根据id取到类的对象  
  50.                 //Object beanObj = this.getBean(name);  
  51.                 // 从beans.xml中根据id取到类的对象  
  52.                 Object beanObj = this.getBean(bean);  
  53.                 System.out.println(beanObj);//com.yyb.dao.impl.UserDAOImpl@a09ee92  
  54.                 // 形成setXXX方法名  
  55.                 String methodName = "set" + name.substring(0, 1).toUpperCase()  
  56.                         + name.substring(1);  
  57.                 System.out.println(name.substring(0, 1).toUpperCase());//U  
  58.                 System.out.println(name.substring(1));//serDAO  
  59.                 System.out.println(methodName);//setUserDAO  
  60.                   
  61.                 // 反射机制对方法进行调用,将对象在加载bean时就注入到环境上下文中  
  62.                 Method m = o.getClass().getMethod(methodName,  
  63.                         beanObj.getClass().getInterfaces()[0]);  
  64.                 System.out.println(o.getClass());//class com.yyb.service.UserService  
  65.                 System.out.println(beanObj.getClass().getInterfaces()[0]);//interface com.yyb.dao.UserDAO  
  66.                 System.out.println(m);//public void com.yyb.service.UserService.setUserDAO(com.yyb.dao.UserDAO)  
  67.                 // 执行注入,相当于执行了一个setXXX(args..)的方法  
  68.                 m.invoke(o, beanObj);  
  69.             }  
  70.         }  
  71.     }  
  72.     @Override  
  73.     public Object getBean(String name)  
  74.     {  
  75.         return beans.get(name);  
  76.     }  
  77. }  

 

 

 

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

 

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

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

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

service.setDao(dao);

 

User:实体类

 

[java] view plain copy
 
 print?
  1. public class User {  
  2.   
  3.     private String userName;    
  4.     private String password;    
  5.     /**  
  6.      * @return the userName  
  7.      */    
  8.     public String getUserName()    
  9.     {    
  10.         return userName;    
  11.     }    
  12.     /**  
  13.      * @param userName  
  14.      *            the userName to set  
  15.      */    
  16.     public void setUserName(String userName)    
  17.     {    
  18.         this.userName = userName;    
  19.     }    
  20.     /**  
  21.      * @return the password  
  22.      */    
  23.     public String getPassword()    
  24.     {    
  25.         return password;    
  26.     }    
  27.     /**  
  28.      * @param password  
  29.      *  the password to set  
  30.      */    
  31.     public void setPassword(String password)    
  32.     {    
  33.         this.password = password;    
  34.     }    
  35.     public String toString()    
  36.     {    
  37.         StringBuffer sb = new StringBuffer();    
  38.         sb.append(this.userName);    
  39.         sb.append(this.password);    
  40.         return sb.toString();    
  41.     }    
  42. }  

 

 

UserDAO

 

[java] view plain copy
 
 print?
  1. public interface UserDAO {  
  2.      void save(User u);    
  3.      void delete();   
  4. }  

 

UserDAOImpl

 

[java] view plain copy
 
 print?
  1. public class UserDAOImpl implements UserDAO {  
  2.      @Override    
  3.         public void save(User u) {    
  4.             System.out.println("User:" + u.toString());    
  5.         }    
  6.         @Override    
  7.         public void delete() {    
  8.             System.out.println("delete User");    
  9.                 
  10.         }    
  11. }  

 

UserService

 

[java] view plain copy
 
 print?
  1. public class UserService {  
  2.       
  3.    private UserDAO userDAO;    
  4.       
  5.    public void addUser(User u)    
  6.     {    
  7.         this.userDAO.save(u);    
  8.     }    
  9.     /**  
  10.      * @return the userDAO  
  11.      */    
  12.     public UserDAO getUserDAO()    
  13.     {    
  14.         return userDAO;    
  15.     }    
  16.     /**  
  17.      * @param userDAO  
  18.      *            the userDAO to set  
  19.      */    
  20.     public void setUserDAO(UserDAO userDAO)    
  21.     {    
  22.         this.userDAO = userDAO;    
  23.     }    
  24. }  

 

 

 

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

 

Client

 

[java] view plain copy
 
 print?
  1. public class client {  
  2.   
  3.     public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, JDOMException, IOException {  
  4.     BeanFactory factory = new ClassPathXmlApplicationContext();   
  5.     //通过工厂直接获取  
  6.         UserService userService = (UserService) factory.getBean("userService");   
  7.         //其实User也可以从工厂中获得  
  8.         User u=(User)factory.getBean("user");  
  9.         //User u = new User();    
  10.         u.setUserName("yyb");    
  11.         u.setPassword("1234");    
  12.         userService.addUser(u);//打印结果yyb1234  
  13.     }  
  14.   
  15. }  

 

 

 

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

 

总结:

 

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

 

Spring IOC实现原理demo:IOC

 

Spring IOC的简单实现

标签:property   delete   内容   工作   method   doc   为我   sdn   void   

原文地址:https://www.cnblogs.com/lijiasnong/p/8406095.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!