模拟spring工作原理

1.配置文件

Service=service.Impl.ServiceImpl

saveDao=dao.daoImpl.saveDaoImpl

2.模拟业务层

--接口 Service

package service;
/**
 * service层
 * @date 2019/10/29 16:42
 */
public interface Service {
    void save() throws IllegalAccessException, InstantiationException, ClassNotFoundException;
}
View Code

--实现 ServiceImpl

package service.Impl;
import factory.BeanFactory;
import service.Service;
import dao.*;
/**
 * 服务层
 * @date 2019/10/29 22:33
 */
public class ServiceImpl implements Service {
    //saveDao dao=new saveDaoImpl();//依赖很高 而且控制权在被调用者

    public void save() throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        int i = 1 ;
        //对象的实例不再由调用者来创建,而是由容器来创建
        saveDao dao =(saveDao) BeanFactory.getBean("saveDao");//使用配置文件和反射解耦(这就是IOC)
        dao.save();
        System.out.println(i+"service");
        i++;
    }
}
//控制反转和依赖注入 一样
View Code

3.工厂BeanFactory

package factory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
 * 一个创建bean对象的工厂
 * bean: 在计算机中,有可重用的组件含义
 * javaBean:用java语言编写的可重用组件
 * javaBean>实体类
 *
 * 第一个:需要一个配置文件配置service和dao
 * 第二个:通过读取配置文件内容,反射创建对象
 * @date 2019/10/29 20:01
 */
public class BeanFactory {
    private static Properties properties;
    //定义一个map,用于存放我们要创建的对象,我们把它称之为容器
    private static Map<String,Object> beans;
    static {
        properties=new Properties();
        InputStream stream = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
        try {
            properties.load(stream);
            //实例化容器
            beans= new HashMap<String, Object>();
            //取出所有配置文件中所有的key
            Enumeration keys = properties.keys();
            //遍历枚举
            while (keys.hasMoreElements()){
                //取出每个key
                String key=keys.nextElement().toString();
                //根据key获取value
                String beanPath = properties.getProperty(key);
                //反射创建对象
                Object value = Class.forName(beanPath).newInstance();
                //存入map
                beans.put(key,value);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
    //根据bean的  名字获取bean对象(单例)
    public static Object getBean(String beanName) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
       /* Object bean= null;
        String property = properties.getProperty(beanName);
        bean = Class.forName(property).newInstance();*/ //此次实例化就使用map了...上面

        return beans.get(beanName);

    }
}
View Code

4.模拟dao层

--接口saveDao

package dao;
/**
 * dao层
 * @date 2019/10/29 16:42
 */
public interface saveDao {
    void save();
}
View Code

--实现类saveDaoImpl

package dao.daoImpl;

import dao.saveDao;

public class saveDaoImpl implements saveDao {
    public void save() {
        System.out.println("dao保存...");
    }
}
View Code

----------测试--------

import factory.BeanFactory;
import service.Impl.ServiceImpl;

/**
 * 模拟三层架构(使用new 会增加耦合性 所以通过 配置文件和反射就会降低耦合  这也就是spring的核心)
 * @date 2019/10/29 16:40
 */
public class test {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
       /* Service service=new ServiceImpl();//在使用new时增强了程序之间的耦合性
        service.save();*/


        for (int i = 0; i < 5; i++) {
            //使用反射 (此方法相当于上面的代码只是解耦了 也就是编译期间不会报错,运行期间会)
            ServiceImpl service =(ServiceImpl) BeanFactory.getBean("Service");
            System.out.println(service);//此时打印的对象都不相同(多例)
            //使用容器后打印的是同一个对像(那么也就提高了代码的性能)
            service.save();
        }
    }
}
View Code

 

posted @ 2020-07-02 22:17  三只坚果  阅读(187)  评论(0编辑  收藏  举报