月度归档:2017年12月

微热山丘,探索 IoC、AOP 实现原理(一) IoC 实现原理

一. 简介及项目设定

1.1 微热山丘 介绍

warmhill(微热山丘)是一个参考 Spring 实现 IoC、AOP 特性的小项目。

相比于 Spring 庞杂的分类、层层继承、抽象,warmhill(微热山丘) 里都是简单直接的类、方法调用,核心在于简洁地展现实现原理。

1.2 项目设定及限制

有如下的限定:
1. 所有的 bean 都是单例。
2. bean 只有一个唯一的标识符 id,没有名字、别名。
3. 所有的 bean 都是立即初始化的,不支持延迟初始化。
4. 对于 BeanPostProcessor 的应用是基于声明的先后顺序。
5. 对于 AOP 的切入点,只支持对方法调用的拦截,不细分 Before/After/Around/Throw 等。
6. 对于 AOP 的配置也是基于 bean 定义的,不支持 <aop:config> 标签。
7. 目前只支持从 XML 方式配置 bean 。
8. bean 的属性目前只支持 String 类型和对其他 bean 的引用,只支持 setter 方法的依赖注入。

二. IoC、AOP 基本概念介绍

  • Resource: 资源。可存放在任意位置,只有一个方法: InputStream getStream();

  • BeanDefinition: bean 的定义信息。

  • BeanDefitionLoader: bean 定义加载类,只有一个方法: List<BeanDefinition> load();

  • BeanFactory: bean 工厂,负责根据 bean 定义创建 bean 的实例。

继续阅读

Spring-MVC 文件上传优化

Spring-MVC 文件上传优化

  1. 配置 CommonsMultipartResolver 时把 maxInMemorySize 配置为合适的大小,让小文件可以缓存在内存中,对磁盘只需一次写操作;

  2. 在 Controller 里调用 multipartFile.transferTo(file); 把文件保存到目标路径。该方法首先进行重命名,如果不成功则进行流拷贝,如果成功则可以省下一次读、写操作。对于 org.apache.commons.fileupload.disk.DiskFileItem 类,调用的方法是下面这个:

public void write(File file) throws Exception {
    if (isInMemory()) {
        FileOutputStream fout = null;
        try {
            fout = new FileOutputStream(file);
            fout.write(get());
        } finally {
            if (fout != null) {
                fout.close();
            }
        }
    } else {
        File outputFile = getStoreLocation();
        if (outputFile != null) {
            // Save the length of the file
            size = outputFile.length();
            /*
             * The uploaded file is being stored on disk
             * in a temporary location so move it to the
             * desired file.
             */
            if (!outputFile.renameTo(file)) {
                BufferedInputStream in = null;
                BufferedOutputStream out = null;
                try {
                    in = new BufferedInputStream(
                        new FileInputStream(outputFile));
                    out = new BufferedOutputStream(
                            new FileOutputStream(file));
                    IOUtils.copy(in, out);
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                            // ignore
                        }
                    }
                    if (out != null) {
                        try {
                            out.close();
                        } catch (IOException e) {
                            // ignore
                        }
                    }
                }
            }
        } else {
            /*
             * For whatever reason we cannot write the
             * file to disk.
             */
            throw new FileUploadException(
                "Cannot write uploaded file to disk!");
        }
    }
}