博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring IOC入门:从Hello world到Spring
阅读量:5806 次
发布时间:2019-06-18

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

从Hello world开始

先上一段代码:

public class HelloWorldTest {    public static void main(String[] args) {        System.out.println("Hello world!");    }}

这是Java里面最简单的一段代码了,做的事情非常简单:控制台打印出“Hello world!”字符串。很明显,这段代码很不好拓展,假如我们想打印别的内容呢?

第一步改动

OK,接下来做一点简单的改动:

public class HelloWorldTest {    public static void main(String[] args) {        if (args.length > 0) {            System.out.println(args[0]);        } else {            System.out.println("Hello world!");        }    }}

这样当我们运行带参数时,控制台会输出我们的第一个参数。这样我们就取得了第一个小小的进步:我们可以不修改代码就控制了不同的输出。但还有问题,这个类既控制了参数的输入,又控制了参数的输出。换句话说就是:消息的输入和输出是耦合在一起的。

进一步解耦

让我们更进一步。首先我们添加一个获取消息的类:

public class MessageConsumer {    public String sayHello(String message) {        if (Objects.isNull(message) || message.length() < 1) {            return "Hello world!";        }        return message;    }}

这样当输入的参数不为null或者空字符串时,输出参数,否则输出Hello world!。调用方只需要在调用的时候传入不同的参数,就达到了输出不同内容的目的。OK,现在已经解耦了消息的输出方,但生产方还在main方法里。接下来解耦消息的生产方。添加一个新的类来生产消息:

public class MessageRenderer {    private MessageConsumer messageConsumer;    public void render(){        if (Objects.isNull(messageConsumer)){            System.out.println("Hello world!");        }else {            System.out.println(messageConsumer.sayHello("MessageRenderer"));        }    }    public MessageConsumer getMessageConsumer() {        return messageConsumer;    }    public void setMessageConsumer(MessageConsumer messageConsumer) {        this.messageConsumer = messageConsumer;    }}

这样主函数只需要new出MessageRenderer和MessageConsumer对象即可,对于消息怎么生产和消费则不需要关心。但这样的问题是MessageRender和MessageConsumer耦合在一起。

面向接口

我们更进一步对两个类进行抽象:

public interface MessageConsumer {    String sayHello(String message);}
public interface MessageRenderer {    void render();    MessageConsumer getMessageConsumer();    void setMessageConsumer(MessageConsumer messageConsumer);}

新建实现类:

public class HelloWorldMessageConsumer implements MessageConsumer {    @Override    public String sayHello(String message) {        return message;    }}
public class HelloWorldMessageRenderer implements MessageRenderer {    private MessageConsumer messageConsumer;    @Override    public void render() {        if (Objects.isNull(messageConsumer)) {            System.out.println("Hello world!");        } else {            System.out.println(messageConsumer.sayHello("HelloWorldMessageRenderer"));        }    }    @Override    public MessageConsumer getMessageConsumer() {        return messageConsumer;    }    @Override    public void setMessageConsumer(MessageConsumer messageConsumer) {        this.messageConsumer = messageConsumer;    }}

程序入口:

public class HelloWorldTest {    public static void main(String[] args) {        MessageRenderer renderer = new HelloWorldMessageRenderer();        MessageConsumer consumer = new HelloWorldMessageConsumer();        renderer.setMessageConsumer(consumer);        renderer.render();    }}

至此,消息的生产和消费解耦开来,生产方只依赖消费方的抽象而不是具体实现,主程序只负责new出需要的生产方和消费方即可。三者的关系如如:

图片描述

运行程序我们可以得到我们想要的输出内容,但还有一点小问题:我们现在要的是HelloWorldMessageConsumer,假如我们需要别的MessageConsumer呢?那就需要改主程序代码了。

简易版IOC

下面我们添加一个类来生产MessageConsumer和MessageRenderer:

public class MessageSupportFactory {    private static MessageSupportFactory instance;    private Properties properties;    private MessageRenderer messageRenderer;    private MessageConsumer messageConsumer;    static {        instance = new MessageSupportFactory();    }    public static MessageSupportFactory getInstance() {        return instance;    }    private MessageSupportFactory() {        properties = new Properties();        try {            properties.load(this.getClass().getResourceAsStream("/msf.properties"));            String rendererClass = properties.getProperty("renderer.class");            String consumerClass = properties.getProperty("consumer.class");            messageRenderer = (MessageRenderer) Class.forName(rendererClass).newInstance();            messageConsumer = (MessageConsumer) Class.forName(consumerClass).newInstance();        } catch (Exception e) {            e.printStackTrace();        }    }    public MessageRenderer getMessageRenderer() {        return messageRenderer;    }    public MessageConsumer getMessageConsumer() {        return messageConsumer;    }}

msg.properties代码如下:

renderer.class=org.chunrun.learn.sp.message.HelloWorldMessageRendererconsumer.class=org.chunrun.learn.sp.message.HelloWorldMessageConsumer

主程序代码如下:

public class HelloWorldTest {    public static void main(String[] args) {        MessageConsumer consumer = MessageSupportFactory.getInstance().getMessageConsumer();        MessageRenderer renderer = MessageSupportFactory.getInstance().getMessageRenderer();        renderer.setMessageConsumer(consumer);        renderer.render();    }}

这样,当我们需要不同的MessageRenderer或MessageConsumer时,只需要在配置文件里指定不同的对象即可。实际上,到这里已经完成了一个简易版的IOC实现。

使用Spring重构

这部分只需要添加配置即可,略。

转载地址:http://xqubx.baihongyu.com/

你可能感兴趣的文章
Jenkins实现单一安卓项目打包多个module填坑实录
查看>>
Python学习手册之Python异常和文件
查看>>
Detours使用说明
查看>>
python 字符串
查看>>
ThreadPoolExecutor源码浅析
查看>>
ImageTag,图片左上侧有一个小标签
查看>>
设计模式分类及典型实现
查看>>
Word替换技巧
查看>>
建立第一个 Yii 应用
查看>>
2016网易游戏实习算法题解(今年找暑期实习的时候参加的)
查看>>
想写个网站
查看>>
windows 开启端口
查看>>
UVa 122 Trees on the level
查看>>
Java实现MD5加密解密类
查看>>
帮助文档的制作javadoc
查看>>
2017-6-8 上传图片加水印,验证码制作
查看>>
JavaSE学习总结第15天_集合框架1
查看>>
js 数据类型问题
查看>>
泛函的延拓
查看>>
csdn搜索技巧
查看>>