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教程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值