自定义SpringIOC的实现(xml+工厂模式+反射)

自定义IOC的实现:
    没有使用IOC技术的环境:
    1.创建工程customIoc,添加依赖(需要添加解析xml的依赖):
        <?xml version="1.0" encoding="UTF-8"?>
        <project xmlns="http://maven.apache.org/POM/4.0.0"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
            <modelVersion>4.0.0</modelVersion>

            <groupId>com.it</groupId>
            <artifactId>customIoc</artifactId>
            <version>1.0-SNAPSHOT</version>

            <properties>
                <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
            </properties>

            <dependencies>
                <!-- 解析 xml 的 dom4j -->
                <dependency>
                    <groupId>dom4j</groupId>
                    <artifactId>dom4j</artifactId>
                    <version>1.6.1</version>
                </dependency>
                <!-- dom4j 的依赖包 jaxen -->
                <dependency>
                    <groupId>jaxen</groupId>
                    <artifactId>jaxen</artifactId>
                    <version>1.1.6</version>
                </dependency>
                <!--单元测试-->
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>4.10</version>
                </dependency>
            </dependencies>

        </project>
        
    2.三层框架模拟:
        2.1 web层
            package com.it.web;
            import com.it.service.UserService;
            import org.junit.Test;
            /**
             * ToDo
             * @author Lyle
             * @date 2020/9/5
             */
            public class UserServlet {
                @Test
                public void doGet(){
                    //获取请求参数
                    //调用业务
                    UserService userService = new UserService();
                    userService.test();
                    //响应结果
                }
            }

        2.2 service层
            package com.it.service;

            import org.junit.Test;

            /**
             * ToDo
             *
             * @author Lyle
             * @date 2020/9/5
             */
            public class UserService {

                /**
                 * 注册
                 */
                public void test(){
                    System.out.println("调用UserDao中的save方法。。。。");
                }
            }

        2.3 dao层:接口+实现类
                    
            public interface UserDao {
                void save();
            }
                        
            public class UserDaoImpl implements UserDao {

                public void save(){
                    System.out.println("save方法保存");
                }
            }
        
    使用IOC技术:
        IOC实现:xml+工厂模式+反射
        1.xml配置:applicationContext.xml
            <?xml version="1.0" encoding="UTF-8"?>
            <beans>
                <!--id属性,作为bean的惟一标识,一般写接口或者类的名字,首字母小写;
                    class属性:写类的全路径名-->
                <bean id="userDao" class="com.it.dao.impl.UserDaoImpl">

                </bean>
            </beans>
            
        2.工厂对象:BeanFactory
            工厂对象解析xml,获取类的全路径名,然后通过反射创建对象,存入Map容器中;
            简单版:
            缺点:
                每次getBean都需要读取文件;
                临时使用的时候才使用反射创建(反射的效率比new要慢)
            package com.it.utils;

            import org.dom4j.*;
            import org.dom4j.io.SAXReader;

            import java.io.IOException;
            import java.io.InputStream;

            /**
             * ToDo
             *
             * @author Lyle
             * @date 2020/9/6
             */
            public class BeanFactory {

                public static Object getBean(String id){
                    InputStream is=null;
                    try {
                        //1.创建SAXReader对象
                        SAXReader saxReader = new SAXReader();
                        //2.读取xml,获得document对象
                        //获取文件流对象
                        is = BeanFactory.class.getClassLoader().getResourceAsStream("applicationContext.xml");
                        Document document = saxReader.read(is);
                        //3.根据id获得bean标签
                        Element beanEle = (Element) document.selectSingleNode("//bean[@id='"+id +"']");
                        //4.获得bean标签的class属性值
                        String className = beanEle.attributeValue("class");
                        //System.out.println(className);
                        //5.根据class属性值(类的全路径名)通过反射创建对象返回
                        Class clazz = Class.forName(String.valueOf(className));
                        Object obj = clazz.newInstance();
                        return obj;
                    } catch (Exception e) {
                        e.printStackTrace();
                        return null;
                    }finally {
                        if (is!=null){
                            try {
                                is.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

               /* public static void main(String[] args) {
                    BeanFactory.getBean("userDao");
                }*/
            }
            
            获取对象时通过这个工厂对象的静态方法获取对象:
                UserDao userDao= (UserDao) BeanFactory.getBean("userDao");    
        终极版:
            将读取文件放入静态代码块,只读取一次;
            程序初始化的时候,创建好对象放入Map容器中,使用时直接从Map容器中获取;
            package com.it.utils;

            import org.dom4j.*;
            import org.dom4j.io.SAXReader;
            import java.io.IOException;
            import java.io.InputStream;
            import java.util.HashMap;
            import java.util.List;
            import java.util.Map;
            /**
             *SpringIOC 工厂对象:读取和解析xml,通过反射创建对象存入Map容器中
             * @author Lyle
             * @date 2020/9/6
             */
            public class BeanFactory {
                //Map容器
                public static Map<String,Object> beanMap=new HashMap<>();
                //静态代码块,解析xml,反射创建对象存入Map容器中
                static {
                    InputStream is=null;
                    try {
                        //1.创建SAXReader对象
                        SAXReader saxReader = new SAXReader();
                        //2.读取xml,获得document对象
                        //获取文件流对象
                        is = BeanFactory.class.getClassLoader().getResourceAsStream("applicationContext.xml");
                        Document document = saxReader.read(is);
                        //获得所有的bean标签,遍历创建好对象存入Map容器中
                        List<Element> baenEles = document.selectNodes("//bean");
                        //遍历
                        for (Element baenEle : baenEles) {
                            //获得bean标签的id和class属性值
                            String id = baenEle.attributeValue("id");
                            String className = baenEle.attributeValue("class");
                            //根据class属性值,通过反射创建好对象存入Map中
                            Object clzss = Class.forName(className).newInstance();
                            beanMap.put(id,clzss);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }finally {
                        if (is!=null){
                            try {
                                is.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                public static Object getBean(String id){
                   return beanMap.get(id);
                }
            }

        


            
            
        
            
            
            
        
            
        

 

posted @ 2020-09-06 11:45  moonlighter  阅读(368)  评论(0编辑  收藏  举报