Spring源码解读 :IOC容器实现Resource(一)

我们在学习Spring源码时都会感叹一句:尼玛,这么多类,看着看着这绕晕了.然后看着看着就看不下去了,累觉不爱啊再见再见,但是想想自己可怜的薪水,不学习如何升职加薪,迎娶白富美呢?所以硬着头皮把Spring源码看完。看完之后发现好像又都忘了大哭大哭不由感叹一番,程序猿真他妈累。为了不让大家重蹈我的覆辙,今天我带大家一起一步一步来实现一个Spring框架(说实现,感觉太厚脸皮了,其实就是把核心代码抽取出来,方便大家阅读)

首先让我们首先来了解一下IOC是个啥东西,官方上说是控制反转,那控制反转又是啥意思呢?就是创建对象的任务交给框架,晕,像我这种单身程序猿每天最大的乐趣就是new Object了,这点权利都要剥夺了。为啥要交给框架呢,就是为了低耦合,框架负责创建对象,也就是说人啊不能花心,乱搞对象,对象太多了关系就容易乱了。

我们把创建对象看做找女朋友,找到女朋友的第一步是得知道女朋友在哪里吧?深圳还是上海还是北京啊。Spring框架创建对象也是首先需要知道对象在什么位置。Spring通过Resource来定位文件的。比如我在D盘上放了一个苍老师的对象 D:\canglaoshi.xml

InputStream in = FileSystemResource(D:\canglaoshi.xml)
噢耶,我们成功跨出第一步:定位到目标了。这么容易啊,一句话的事就搞定了,其实得感谢Spring同志,它就相当于婚姻中介所,帮你搭桥牵线。我们来看看Spring同志如何帮我们完成的

public interface InputStreamSource {
    public InputStream getInputStream() throws IOException;// 直接返回一个InputStream
}
我们首先来看看Resouce。你可以把它当做对象资源,也就是备胎了。

public interface Resource {
	
	boolean exists(); // 妹子是否存在
	
	boolean isReadable();//这个对象能不能接近,也许人家是高冷女神,这个时候我们还是放弃吧,屌丝程序猿无法拿下的 
	
	boolean isOpen();// 是否名花有主了,Spring是不允许任何人挖墙脚的,毕竟这样是不道德的。
	
	URL getURL() throws IOException;//就是告诉你妹子的地址,光有地址你不一定找得到,万一恰巧妹子不在呢
	
	URI getURI() throws IOException;//把地址和电话号码一起都告诉你了,这样你就可以找的妹子咯
	
	File getFile() throws IOException;//就是获得你硬盘的苍老师对象了,这个最简单了,相信大家都能找到
	
	String getFilename();//妹子的名字
	
	String getDescription();//妹子的身高,体重,三维信息了
}

AbstractResource代表一个抽象的资源,实现了一些公共的方法。看看下面的方法,心塞啊,看到abstract,你没有交费,想获得资源,门都没有。

public abstract class AbstractResource implements Resource {

    /**
     * 你电脑里有没有下载苍老师
     */
    @Override
    public boolean exists() {
        try {
            return getFile().exists();
        }
        catch(IOException ex) {
            try {
                InputStream is = getInputStream();
                is.close();
                return true;
            }
            catch (Throwable isEx) {
                return false;
            }
        }
    }

    /**
     * 一般妹子都会给你一个接近的机会的
     */
    @Override
    public boolean isReadable() {
        return true;
    }

    /**
     * 判断文件是否可以被打开,你还不是会员,当然不能打开
     */
    @Override
    public boolean isOpen() {
        return false;
    }
    /**
     * 我是不会告诉你地址的,除非你升级为FileSystemResource获取其他会员,你要是用强,我死给你看
     */
    @Override
    public URL getURL() throws IOException {
        throw new FileNotFoundException(getDescription()+"cannot be resolved to URL");
    }
    /**
     * 如果你能获得我的URL,我就给机会让你获得URI
     */
    @Override 
    public URI getURI() throws IOException {
        URL url = getURL();
        try {
            return ResourceUtils.toURI(url);
        }
        catch (URISyntaxException ex) {
            throw new IOException("Invalid URI [" + url + "]", ex);
        }
    }
    /**
     * 嘿,别费心了,你找不到我的
     */
    @Override
    public File getFile() throws IOException {
        throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");
    }
    /**
     * 我不是一个随便的人,我的名字你休想知道
     */
    @Override
    public String getFilename() {
        return null;
    }

    @Override
    public String toString() {
        return getDescription();
    }

    @Override
    public boolean equals(Object obj) {
        return (obj == this ||
                (obj instanceof Resource && ((Resource) obj).getDescription().equals(getDescription())));
    }

    @Override
    public int hashCode() {
        return getDescription().hashCode();
    }
要找到对象,还是得升级会员,每人交10块钱,先来一个初级会员FileSystemResource吧

public class FileSystemResource extends AbstractResource implements WritableResource{

    private final File file;// 这就是仓老师了,交了10块钱,终于见到了你

    private final String path;// 仓老师的地址
    /**
     *通过File,桌面快捷方式,就可以找到苍老师的资源了 
     */
    public FileSystemResource(File file) {
        this.file = file;
        this.path = file.getPath();
    }
    /**
     *通过路径,比如D:\canglaoshi,就可以找到苍老师的资源了 
     */
    public FileSystemResource(String path) {
        this.file = new File(path);
        this.path = path;
    }
    /**
     *通过File就可以获得URL了
     */
    @Override
    public URL getURL() throws IOException {
        return this.file.toURI().toURL();
    }

    @Override
    public URI getURI() throws IOException {
        return this.file.toURI();
    }

    @Override
    public File getFile() throws IOException {
        return this.file;
    }

    public final String getPath() {
        return this.path;
    }

    @Override
    public boolean exists() {
        return this.file.exists();
    }

    @Override
    public boolean isReadable() {
        return (this.file.canRead() && !this.file.isDirectory());
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new FileInputStream(this.file);
    }

    @Override
    public boolean isWritable() {
        return (this.file.canWrite() && !this.file.isDirectory());
    }

    @Override
    public OutputStream getOutputStream() throws IOException {
        return new FileOutputStream(this.file);
    }

    @Override
    public String getDescription() {
        return "file [" + this.file.getAbsolutePath() + "]";
    }

    @Override
    public boolean equals(Object obj) {
        return (obj == this ||
                        (obj instanceof FileSystemResource &&  this.path.equals(((FileSystemResource) obj).path)));
    }

    @Override
    public int hashCode() {
        return this.path.hashCode();
    }

}
升级为初级会员真好,所有的信息都可以获得了,等下,看看AbstractResource 实现了WritableResource,这是一个什么东东??

public interface WritableResource extends Resource {

    /**
     *是否可以改造妹子
     */
    boolean isWritable();

    /**
     * 获得改造妹子的工具OutputStream 
     */
    OutputStream getOutputStream() throws IOException;

}
Spring兄真好,还提供这种特殊服务,但是想想还是先算了,我们一般不会有机会改造妹子的,找到了都算不错了,还改造,小心以后妹子直接甩了你。











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值