模拟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; }
--实现 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++; } } //控制反转和依赖注入 一样
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); } }
4.模拟dao层
--接口saveDao
package dao; /** * dao层 * @date 2019/10/29 16:42 */ public interface saveDao { void save(); }
--实现类saveDaoImpl
package dao.daoImpl; import dao.saveDao; public class saveDaoImpl implements saveDao { public void save() { System.out.println("dao保存..."); } }
----------测试--------
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(); } } }