主类
package com.example.demo;
import com.application.Application;
public class Demo {
    public static void main(String[] args) {
        Application application = new Application("application.properties");
        application.run();
    }
}
 
创建对象,需要的参数(配置文件相对类路径下的路径)
Application("application.properties")
Application类
package com.application;
public class Application {
    //配置文件路径 默认为application.properties
    private String path = "application.properties";
    public Application(String path){
        this.path = path;
    }
    public Application(){
    }
    public void  run(){
        //配置信息
        Environment environment = new Environment(this.path);
        ApplicationBannerPrinter bannerPrinter = new ApplicationBannerPrinter();
        //打印 banner
        bannerPrinter.print(environment,System.out);
    }
}
 
Environment类(存放配置信息)
package com.application;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class Environment {
    //存放配置信息
    private Properties properties = new Properties();
    //配置文件路径
    private String path;
    public String getProperty(String key, String defualtValue){
        String value = this.properties.getProperty(key, defualtValue);
        return value;
    }
    public Environment(String path){
        this.path = path;
        getPropertiesFromPropertiesFile(path);
    }
    //读取配置文件
    public Properties getPropertiesFromPropertiesFile(String path){
        ClassPathResource classPathResource = new ClassPathResource(path,null);
        InputStream in = null;
        try {
            //获取配置文件的输入流
            in = classPathResource.getInputStream();
            //读取配置文件将信息存放到 properties 中
            this.properties.load(in);
            return this.properties;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
 
public Environment(String path){ this.path = path; getPropertiesFromPropertiesFile(path); }通过这个构造方法创建对象时,调用getPropertiesFromPropertiesFile(path);读取配置文件
ClassPathResource类(通过该类加载类路径下的资源)
package com.application;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
//用于加载类路径下的资源
public class ClassPathResource {
     private String path;
    private ClassLoader classLoader;
    public ClassPathResource(String path, ClassLoader classLoader) {
        String pathToUse = path;
        if (pathToUse.startsWith("/")) {
            pathToUse = pathToUse.substring(1);
        }
        this.path = pathToUse;
        this.classLoader = (classLoader != null ? classLoader : Thread.currentThread().getContextClassLoader());
    }
    //判断资源是否存在
    public boolean exists() {
        return resolveURL() != null;
    }
    protected URL resolveURL() {
        try {
            if (this.classLoader != null) {
                return this.classLoader.getResource(this.path);
            }
            else {
                return ClassLoader.getSystemResource(this.path);
            }
        }
        catch (IllegalArgumentException ex) {
            return null;
        }
    }
    //获取资源的输入流
    public InputStream getInputStream() throws IOException {
        return this.classLoader.getResourceAsStream(this.path);
    }
}
 
ApplicationBannerPrinter类(负责打印banner)
package com.application;
import java.io.PrintStream;
public class ApplicationBannerPrinter {
    //banner location 配置项的key
    static final String BANNER_LOCATION_PROPERTY = "application.banner.location";
    //默认的banner location
    static final String DEFAULT_BANNER_LOCATION = "banner.txt";
    // 默认banner
    private static final Banner DEFAULT_BANNER = new ApplicationBanner();
    public void print(Environment environment, PrintStream out){
        //根据情况获取不同的Banner实现类对象
        Banner banner = getBanner(environment);
        //打印banner(不同的Banner实现类对象的 printBanner方法不同)
        banner.printBanner(environment,  out);
    }
    private Banner getBanner(Environment environment){
        //获取资源文件中的banner图
        Banner banner = getTextBanner(environment);
        //成功获取banner图资源
        if(banner != null){
            return banner;
        }
        //否则 返回 默认banner
        return DEFAULT_BANNER;
    }
    private Banner getTextBanner(Environment environment) {
        // 根据key(第一个参数) 获取banner的location,获取失败(未配置该配置项),返回默认值(第二个参数)
        String location = environment.getProperty(BANNER_LOCATION_PROPERTY, DEFAULT_BANNER_LOCATION);
        //用于加载 location 资源文件的 resource
        ClassPathResource resource = new ClassPathResource(location,null);
        // 如果 location 资源文件存在,返回打印该 banner的 Banner实现类对象
        if ( resource.exists() ) {
            return new ResourceBanner(resource);
        }
        return null;
    }
}
 
打印banner分为两种情况:
1.用户为提供banner图,打印默认的banner
2.用户提供了banner图,打印用户提供的banner图
根据情况获取不同的Banner实现类,不同的Banner实现类中对printBanner方法的具体实现不同,由此打印不同的banner 图
private Banner getBanner(Environment environment){ //获取资源文件中的banner图 Banner banner = getTextBanner(environment); //成功获取banner图资源 if(banner != null){ return banner; } //否则 返回 默认banner return DEFAULT_BANNER; }
Banner接口,printBanner方法用于打印banner
package com.application;
import java.io.PrintStream;
public interface Banner {
    void printBanner(Environment environment, PrintStream printStream);
}
 
ApplicationBanner实现Banner接口,负责打印默认Banner
package com.application;
import java.io.PrintStream;
public class ApplicationBanner implements Banner {
    //默认 banner
    private static final String[] BANNER = { "", "  .   ____          _            __ _ _",
            " /\\\\ / ___'_ __ _ _(_)_ __  __ _ \\ \\ \\ \\", "( ( )\\___ | '_ | '_| | '_ \\/ _` | \\ \\ \\ \\",
            " \\\\/  ___)| |_)| | | | | || (_| |  ) ) ) )", "  '  |____| .__|_| |_|_| |_\\__, | / / / /",
            " =========|_|==============|___/=/_/_/_/" };
    @Override
    public void printBanner( Environment environment,  PrintStream out) {
        for (String line : BANNER) {
            out.println(line);
        }
    }
}
 
ResourceBanner实现Banner接口,负责打印用户提供的放在类路径下的banner
package com.application;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
public class ResourceBanner implements Banner{
    //加载资源文件的resource
    private ClassPathResource resource;
    public ResourceBanner(ClassPathResource resource){
        this.resource = resource;
    }
    @Override
    public void printBanner(Environment environment, PrintStream out) {
            try {
                //StreamUtils.copyToString用于将输入流中的内容拷贝到字符串中,第二个参数指定要用的字符集
                //获取 banner 的字符串
                String banner = StreamUtils.copyToString(this.resource.getInputStream(), StandardCharsets.UTF_8);
                //输出banner字符串
                out.println(banner);
            }
            catch (Exception ex) {
                System.out.println("Banner not printable");
                ex.printStackTrace();
            }
    }
}
 
StreamUtils.copyToString用于将输入流中的内容拷贝到字符串中
package com.application;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
public class StreamUtils {
    //默认缓冲区大小
    public static final int BUFFER_SIZE = 4096;
    //用于将输入流中的内容拷贝到字符串中
    public static String copyToString(InputStream in, Charset charset) throws IOException {
        if (in == null) {
            return "";
        }
        //创建了一个初始容量为 BUFFER_SIZE 的 StringBuilder 对象
        StringBuilder out = new StringBuilder(BUFFER_SIZE);
        //将字节流in转换成字符流,所用的字符集为 charset
        InputStreamReader reader = new InputStreamReader(in, charset);
        char[] buffer = new char[BUFFER_SIZE];
        int charsRead;
        //reader.read(buffer) 将数据读到 buffer 中,返回值为读取到的字符 长度
        while ((charsRead = reader.read(buffer)) != -1) {
            //将读取的字符追加到 out 之后
            out.append(buffer, 0, charsRead);
        }
        return out.toString();
    }
}
 
test1:
配置文件application.properties(没有内容)
 
 public static void main(String[] args) {
    //Application application = new Application("application.properties");
    Application application = new Application();
    application.run();
} 
 
打印默认banner
 
test2:
配置文件 application1.properties(没有内容)
提供了banner.txt
public static void main(String[] args) { Application application = new Application("application1.properties"); //Application application = new Application(); application.run(); }
打印banner.txt
 
test3:
在test2,上 改banner.txt 文件名 为 banner2.txt
打印默认banner(默认会先检查banner.txt是否存在,不存在则打印默认banner)

test4:
public static void main(String[] args) { Application application = new Application("application1.properties"); //Application application = new Application(); application.run(); }
application1.properties:
application.banner.location=banner2.txt
 
打印banner2.txt




















