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-入门的主要内容,如果未能解决你的问题,请参考以下文章

Spring入门IOC和AOP学习笔记

spring入门篇2 --- IOC设计思想

Spring学习笔记3:IOC快速入门其他配置

慕课-《Spring入门篇》学习笔记 专题一 IOC

Java框架型项目从入门到装逼第一节 - Spring框架 IOC的丧心病狂解说

Spring入门导读——IoC和AOP