
一个小程序以理解控制反转
发布日期:2021-05-07 06:54:35
浏览次数:20
分类:技术文章
本文共 3309 字,大约阅读时间需要 11 分钟。
IOC即“控制反转”,即是将创建对象的操作,赋予给程序,而不需要程序员手动去修改代码,以达到解耦的效果,这部分的博文网上有很多,就不过多解释了
1. 实现思路
使用配置文件的方式,让程序运行时动态读取配置文件,从而得知要创建的对象的名字,然后通过反射机制动态创建该对象,从而实现控制反转2. 控制反转的简单实现
① 创建以下层级目录及配置文件 ② 编写factory.properties配置文件内容
helloDao=com.ruoxi.dao.impl.HelloDaoImpl
② 编写dao层
HelloDaoImpl.class
public class HelloDaoImpl implements HelloDao { public HelloDaoImpl(){ }; @Override public ListfindAll() { return Arrays.asList("1","2","3","4","5"); }}
③ 创建一个Bean工厂,以提供生产HelloDaoImpl的实例
重点:
这里使用HashMap来模拟缓存,通过判断key是否存在来实现单例
如何实现控制反转?
(1) 通过properties.getProperty()函数,获取配置文件中的内容,以一个字符串接收,从而得到全类名
(2) 得到全类名,那么就可以调用Class.forName()得到对应的Class对象
(3) 得到Class对象,那么就可以创建一个对应类的实例(这里即是HelloDaoImpl)
具体见代码注释
public class BeanFactory { private static Properties properties = new Properties(); // 使用HashMap模拟缓存 private static Mapcache = new HashMap<>(); //用静态代码块初始化属性值 static { try { properties.load(BeanFactory.class.getClassLoader().getResourceAsStream("factory.properties")); //即factory.propertise配置文件 } catch (IOException e) { e.printStackTrace(); } } //传入参数beanName即为需要创建的实例名字 public static Object getDao(String beanName) { // 模拟IOC的单例模式 只能创建一个同名的bean 从缓存存取 // 如果缓存不存在名为beanName的bean,才进行初始化 if(!cache.containsKey(beanName)){ // 利用synchronized,确保多线程下的单例模式 synchronized (BeanFactory.class){ try { //读取配置文件中的值,用value来接收 String value = properties.getProperty(beanName); // value获取的即是配置文件中名为"helloDao"的接收值 //利用反射机制创建对象 这里创建的是名为value值的对象 Class clazz = Class.forName(value); Object object = clazz.getDeclaredConstructor(null).newInstance(null); //将bean名和object存入缓存 cache.put(beanName,object); return object; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } } return null; }}
④ 编写service层,调用dao层的函数
public class HelloServiceImpl implements HelloService { private HelloDao helloDao = (HelloDao) BeanFactory.getDao("helloDao"); @Override public ListfindAll() { return helloDao.findAll(); }}
⑤ 编写HelloSerlvet.class进行测试
@WebServlet("/hello")public class HelloServlet extends HttpServlet { private HelloService helloService = new HelloServiceImpl(); @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write(this.helloService.findAll().toString()); }}
至此,简单的控制反转功能已经实现,为何这么说?
因为,当需要改变BeanFactory(bean工厂)生产的对象实例时,不需要再去改动java代码,只需要改动factory.properties中的内容 (这里即是右侧的HelloDaoImpl,如果需要生产其他实例则修改至对应的全类名即可)
helloDao=com.ruoxi.dao.impl.HelloDaoImpl
即是将生成对象实例的操作交给了程序,不需要改动代码,也就是达到了控制反转的功能
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2025年03月20日 20时44分07秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
使用async、await改善异步代码
2021-05-07
零基础入门JavaScript 这一篇笔记就够了
2021-05-07
MySQL_安全管理、表单传值、php操作
2021-05-07
B1021 个位数统计 (15 分)
2021-05-07
Idiot 的间谍网络
2021-05-07
MySql索引及使用、实现的数据结构
2021-05-07
初探SSRF漏洞
2021-05-07
pythonBug入门——从零开始学python
2021-05-07
js-禁止右键菜单代码、禁止复制粘贴代码
2021-05-07
SpringBoot中使用Mybatis访问MySQL数据库(使用xml方式)
2021-05-07
SSLOJ1692 USACO 3.2 Magic Squares 魔板&P2730
2021-05-07
数组--Go语言学习笔记
2021-05-07
Redis (三)——Linux 上安装 Redis
2021-05-07
java 重写(override)和重载(overload)区别
2021-05-07
java 多态类型转换
2021-05-07
常用正则表达式
2021-05-07
XML:采用XHTML和CSS设计可重用可换肤的WEB站点
2021-05-07
Tomcat6中web项目部署路径webapps和wtpwebapps的区别
2021-05-07
Java判断字符串是否为金额
2021-05-07
软件架构-zookeeper快速入门
2021-05-07