spring学习-IOC-入门
Posted 懒佯佯大哥
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring学习-IOC-入门相关的知识,希望对你有一定的参考价值。
在讲spring的IOC之前,我们先看一个示例
- 三层视图的示例
package bean1;
// service层
public class CallService
private static CallDao callDao = new CallDao();
public void call()
System.out.println("这是CallService");
callDao.save();
// dao层
class CallDao
public void save()
System.out.println("开始保存Call...");
// vo层
class CallVo
private static CallService callService = new CallService();
public void voCall()
System.out.println("这是VoCall...");
callService.call();
// 测试类
class TestCall
public static void main(String[] args)
CallVo callVo = new CallVo();
callVo.voCall();
从示例中,我们看到,每当需要调用某个类的时候,总是需要先new一个对象出来。
试想一下,如果我们有很多的类,那么我们需要反复不断的声明。
并且,过多的对象,也会造成系统性能的下降。
那么,是否可将这些new的操作,交给一个工厂来操作呢?
-
工厂创建对象
工厂创建的时候,如果直接根据名称创建,那么我们需要不断去修改代码完善,违反OCP(开闭)原则。
那么此时,我们是否可以考虑一下,将名称与类的对应关系,用一个配置文件描述?- 定义bean1.properties配置文件:
# bean1.properties文件 CallService=bean1.CallService CallDao=bean1.CallDao
- 声明工厂类-静态代码块Properties加载配置文件
class BeanFactory private static Properties properties = new Properties(); static InputStream ras = BeanFactory.class.getClassLoader().getResourceAsStream("bean1.properties"); try properties.load(ras); catch (IOException e) e.printStackTrace(); throw new ExceptionInInitializerError("初始化BeanFactory失败"); public static Object getBean(String name) String property = properties.getProperty(name); try return Class.forName(property).newInstance(); catch (InstantiationException e) e.printStackTrace(); catch (IllegalAccessException e) e.printStackTrace(); catch (ClassNotFoundException e) e.printStackTrace(); return null;
- 测试
class TestCall public static void main(String[] args) for (int i = 0; i < 5; i++) Object callService = BeanFactory.getBean("CallService"); System.out.println(callService);
- 结果
bean1.CallService@4b1210ee bean1.CallService@4d7e1886 bean1.CallService@3cd1a2f1 bean1.CallService@2f0e140b bean1.CallService@7440e464
可以看到,可以正常的获取到类对象
但同时,我们发现,每次getBean的时候,都会生成新的对象,这个并不是我们想要的,因为,频繁的创建对象会造成性能损失、内存消耗。
这种场景下,单例模式的可能会更适合我们
因此,我们需要有一个 “容器” 来保存实例化的对象,从而引出了容器的概念
- 容器保存功能的工厂模式:
class BeanFactory
private static Properties properties = new Properties();
// 存储一个map保存beans---相当于一个容器的概念:类比IOC容器
private static Map<String, Object> beans = new HashMap<>();
static
InputStream ras = BeanFactory.class.getClassLoader().getResourceAsStream("bean1.properties");
try
properties.load(ras);
for (String pro:properties.stringPropertyNames())
beans.put(pro, Class.forName(properties.getProperty(pro)).newInstance());
catch (IOException | ClassNotFoundException e)
e.printStackTrace();
throw new ExceptionInInitializerError("初始化BeanFactory失败");
catch (IllegalAccessException e)
e.printStackTrace();
catch (InstantiationException e)
e.printStackTrace();
public static Object getBean(String name)
return beans.getOrDefault(name, null);
此时,测试的结果,每个实例的地址都是一样的了:
bean1.CallService@75828a0f
bean1.CallService@75828a0f
bean1.CallService@75828a0f
bean1.CallService@75828a0f
bean1.CallService@75828a0f
- IOC容器
从上面的示例,我们引出了工厂模式+“容器”,实现单例对象的创建。
从而我们引出了IOC的概念:Inversion Of Controller,控制反转。
我们可以这么理解:当我们想要一个类的时候,可以new对象,也可以从一个BeanFactory中获取一个。而IOC呢,是将我们new的操作,交给了spring容器统一管理,也就是将控制权交给spring统一处理
意义:IOC容器的引入,一定程度上简化了我们对对象的操作,降低了耦合性
IOC包括:DI(依赖注入Dependency Injection) 和依赖查找Dependency Lookup,后续我们逐步分解
参考:
- IT黑马spring教程
以上是关于spring学习-IOC-入门的主要内容,如果未能解决你的问题,请参考以下文章