博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring IoC-02
阅读量:4692 次
发布时间:2019-06-09

本文共 4175 字,大约阅读时间需要 13 分钟。

     IoC顾名思义为“控制反转”,就是反转资源获取的方向,容器主动将资源注入到它所管理的组件里,组件所要做的工作仅仅是选择一种合适的方式接受资源。而传统的思维方式是:当一个组件需要外部资源时,组件会向容器发送查找资源的请求,容器再将找到的资源传送给该组件。由此开来IoC的优势是组件不需要知道如何获取资源,只需要选择接受资源的方式,从而降低的模块之间的耦合度,也是体现出这种设计原则优点。

    说道IoC就不得不说DI(依赖注入),其实他们的设计思想是相同的,不过DI是IoC的一个良好的实现。下面来说说DI所做的工作:

    在DI模式下,容器全权负责组件的装配工作,容器会将一些之前定义好的方式(如setter方法或构造函数)将匹配的资源注入到每个组件里。

    .setter注入     setter注入会存在一些问题,1.容易出现忘记调用setter方法注入组件所需要的依赖,将会导致NullPointetException异常。2.代码会存在安全问题,第一次注入后,不能阻止再次调用setter,除非添加额外的处理工作。

    .构造器注入     构造器注入能够一定程度上解决setter注入的问题。但是该注入方式也会带来一些问题,如果组件有很多的依赖,则构造函数的参数列表将会变得冗长,会降低代码的可读性。

    .接口注入        该注入的方式使用的非常少,它要求组件必须实现某个接口,容器是透过这个接口实现注入依赖的。接口注入的缺点比较明显,使用接口注入需要实现特定的接口,而接口又特定与容器,所以组件对容器产生依赖,一旦脱离容器,组件不能重用。这是一种“侵入式”注入。

     由此可见常用到的注入方式是:setter和构造器注入

/*生成报表的通用接口*/public interface ReportBuilder{    public void build(String data);}

 

/*生成HTML格式报表*/public class ReportHtmlBuilder implements ReportBuilder {    @Override    public void build(String data) {        /*示意代码*/        System.out.println("build html report!");    }}/*生成PDF格式报表*/public class ReportPdfBuilder implements ReportBuilder {    @Override    public void build(String data) {        System.out.println("build pdf report!");    }}

 

/*报表服务类*/public class ReportService {    /*依赖"ReportBuilder"*/    private ReportBuilder builder;        public ReportBuilder getBuilder()    {        return builder;    }        /*setter注入*/    public void setBuilder(ReportBuilder builder)    {        this.builder = builder;    }    public void builderYearReport(int year)    {        this.builder.build("data");    }}

 

//IoC容器配置文件"component.properties"pdfBuilder=com.beliefbitrayal.ioc.inter.imp.ReportPdfBuilderhtmlBuilder=com.beliefbitrayal.ioc.inter.imp.ReportHtmlBuilderreportService=com.beliefbitrayal.ioc.server.ReportServicereportService.builder=htmlBuilder

 

//IoC容器public class Container{    /*用于储存Component的容器*/    private Map
repository = new HashMap
(); public Container() { try { /*读取容器配置文件"component.properties"*/ Properties properties = new Properties(); properties.load(new FileInputStream("src/component.properties")); /*获取配置文件的每一行信息*/ for(Map.Entry
entry : properties.entrySet()) { String key = (String)entry.getKey(); String value = (String)entry.getValue(); /*处理配置文件的每一行信息*/ this.handler(key, value); } } catch (Exception e) { e.printStackTrace(); } } private void handler(String key,String value) throws Exception { /* * reportService=com.beliefbitrayal.ioc.server.ReportService * reportService.builder=htmlBuilder * 第一种情况,key值中间没有"."说明为一个新组件。对它的处理为创建它的对象,将其对象放入Map中。 * 第二种情况,key值中间出现"."说明这个属性条目是一个依赖注入。根据"."的位置将这个key值划分为两部分,第一部分为组件的名字,第二部分为 * 该组件需要设置的属性。 */ String[] parts = key.split("\\."); /*情况1*/ if(parts.length == 1) { /*通过反射的方式创建组件的对象*/ Object object = Class.forName(value).newInstance(); this.repository.put(key, object); } else { /*对于情况2,首先用key值的第一部分(组件名)获取组件*/ Object object = this.repository.get(parts[0]); /*再使用value值指定的组件名从Map对象中获取依赖*/ Object reference = this.repository.get(value); /*将获取的依赖注入到指定的组件的相应属性上,"PropertyUtils"类属于Apache下Commons BeanUtil第三方类库, * 要使用它还需要下载Commons Logging第三方类库 */ PropertyUtils.setProperty(object, parts[1], reference); } } public Object getComponent(String key) { return this.repository.get(key); }}

 

//根据配置文件,我们在场景类中使用的报表应该是HTML格式的:public class Client{    public static void main(String[] args)    {        /*创建容器*/        Container container = new Container();                /*从容器中获取"报表服务类"*/        ReportService reportService = (ReportService)container.getComponent("reportService");                /*显示报表*/        reportService.builderYearReport(0);    }}

 

 

转载于:https://www.cnblogs.com/GenghisKhan/archive/2012/02/08/2342300.html

你可能感兴趣的文章
python 二维字典
查看>>
pip 警告!The default format will switch to columns in the future
查看>>
Arrays类学习笔记
查看>>
实验吧之【天下武功唯快不破】
查看>>
2019-3-25多线程的同步与互斥(互斥锁、条件变量、读写锁、自旋锁、信号量)...
查看>>
win7-64 mysql的安装
查看>>
dcm4chee 修改默认(0002,0013) ImplementationVersionName
查看>>
maven3在eclipse3.4.2中创建java web项目
查看>>
发布时间 sql语句
查看>>
黑马程序员 ExecuteReader执行查询
查看>>
记一些从数学和程序设计中体会到的思想
查看>>
题目1462:两船载物问题
查看>>
POJ 2378 Tree Cutting(树形DP,水)
查看>>
第二冲刺阶段个人博客5
查看>>
UVA 116 Unidirectional TSP (白书dp)
查看>>
第三方测速工具
查看>>
MySQL 网络访问连接
查看>>
在aws ec2上使用root用户登录
查看>>
数据访问 投票习题
查看>>
CIO知识储备
查看>>