zoukankan      html  css  js  c++  java
  • Spring IOC的简单实现

    简单的说,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

  • 相关阅读:
    web知识共享网站
    Javascript模拟多线程
    让mssql查询的参数大小写区分
    asp.net导出excel文件方法之一
    对生活迷茫时,可以看的小说..
    解决SWFUpload在Chrome、Firefox浏览器下session找不到的问题
    fckeditor在ie9无法上传图片和弹出浮层内容不显示的解决方法
    一个javascript文件上传组件.
    css属性之媒体(Media)类型
    前端问题汇总
  • 原文地址:https://www.cnblogs.com/lijiasnong/p/8406095.html
Copyright © 2011-2022 走看看