spring boot源码学习 SpringApplication(一)

启动类
SpringApplication关键代码

new SpringApplication(primarySources).run(args)

主要看一下 构造方法,和run方法
代码执行流程不记录,自己debug
只是记录一下涉及到的比较重要的类,期间可以学到一些相关的设计思想吧

org.springframework.util.StopWatch 记录服务的启动时间
org.springframework.boot.StartupInfoLogger打印启动信息的日志

StartupInfoLogger logger = new StartupInfoLogger(this.mainApplicationClass);
logger.logStarting(getApplicationLog());
logger.logStarted(getApplicationLog(), stopWatch);


    /**
     * Returns the {@link Log} for the application. By default will be deduced.
     * @return the application log
     */
    protected Log getApplicationLog() {
        if (this.mainApplicationClass == null) {
            return logger;
        }
        return LogFactory.getLog(this.mainApplicationClass);
    }

可以看到StartupInfoLogger 设计的时候 并没有设置具体的log实现类,而是通过springboot传入的

private StringBuilder getStartedMessage(StopWatch stopWatch) {
        StringBuilder message = new StringBuilder();
        message.append("Started ");
        message.append(getApplicationName());
        message.append(" in ");
        message.append(stopWatch.getTotalTimeSeconds());
        try {
        ###### 注意这里打印jvm的运行时间
            double uptime = ManagementFactory.getRuntimeMXBean().getUptime() / 1000.0;
            message.append(" seconds (JVM running for " + uptime + ")");
        }
        catch (Throwable ex) {
            // No JVM time available
        }
        return message;
    }

org.springframework.boot.ApplicationPid

public class ApplicationPid {

    private static final PosixFilePermission[] WRITE_PERMISSIONS = {
            PosixFilePermission.OWNER_WRITE, PosixFilePermission.GROUP_WRITE,
            PosixFilePermission.OTHERS_WRITE };

    private final String pid;

    public ApplicationPid() {
        this.pid = getPid();
    }
    private String getPid() {
        try {
            // 通过jvm获取进程id
            String jvmName = ManagementFactory.getRuntimeMXBean().getName();
            return jvmName.split("@")[0];
        }
        catch (Throwable ex) {
            return null;
        }
    }
    // 判断文件是否可写
private void assertCanOverwrite(File file) throws IOException {
        if (!file.canWrite() || !canWritePosixFile(file)) {
            throw new FileNotFoundException(file.toString() + " (permission denied)");
        }
    }

    private boolean canWritePosixFile(File file) throws IOException {
        try {
            Set<PosixFilePermission> permissions = Files
                    .getPosixFilePermissions(file.toPath());
            for (PosixFilePermission permission : WRITE_PERMISSIONS) {
                if (permissions.contains(permission)) {
                    return true;
                }
            }
            return false;
        }
        catch (UnsupportedOperationException ex) {
            // Assume that we can
            return true;
        }
    }

还有一个比较重要的类 可以学习一下

ApplicationHome
核心用法 class.getProtectionDomain().getCodeSource().getLocation()

private File findSource(Class<?> sourceClass) {
        try {
            ProtectionDomain domain = (sourceClass == null ? null
                    : sourceClass.getProtectionDomain());
            CodeSource codeSource = (domain == null ? null : domain.getCodeSource());
            URL location = (codeSource == null ? null : codeSource.getLocation());
            File source = (location == null ? null : findSource(location));
            if (source != null && source.exists() && !isUnitTest()) {
                return source.getAbsoluteFile();
            }
            return null;
        }
        catch (Exception ex) {
            return null;
        }
    }

    private boolean isUnitTest() {
        try {
            for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
                if (element.getClassName().startsWith("org.junit.")) {
                    return true;
                }
            }
        }
        catch (Exception ex) {
        }
        return false;
    }

    private File findSource(URL location) throws IOException {
        URLConnection connection = location.openConnection();
        if (connection instanceof JarURLConnection) {
            return getRootJarFile(((JarURLConnection) connection).getJarFile());
        }
        return new File(location.getPath());
    }

    private File getRootJarFile(JarFile jarFile) {
        String name = jarFile.getName();
        int separator = name.indexOf("!/");
        if (separator > 0) {
            name = name.substring(0, separator);
        }
        return new File(name);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值