本文主要研究一下springboot的SpringPropertyAction

SpringBootJoranConfigurator

org/springframework/boot/logging/logback/SpringBootJoranConfigurator.java

class SpringBootJoranConfigurator extends JoranConfigurator {

    private LoggingInitializationContext initializationContext;

    SpringBootJoranConfigurator(LoggingInitializationContext initializationContext) {
        this.initializationContext = initializationContext;
    }

    @Override
    public void addInstanceRules(RuleStore rs) {
        super.addInstanceRules(rs);
        Environment environment = this.initializationContext.getEnvironment();
        rs.addRule(new ElementSelector("configuration/springProperty"), new SpringPropertyAction(environment));
        rs.addRule(new ElementSelector("*/springProfile"), new SpringProfileAction(environment));
        rs.addRule(new ElementSelector("*/springProfile/*"), new NOPAction());
    }

}
SpringBootJoranConfigurator继承了JoranConfigurator,其addInstanceRules添加了configuration/springProperty的动作为SpringPropertyAction

SpringPropertyAction

org/springframework/boot/logging/logback/SpringPropertyAction.java

class SpringPropertyAction extends Action {

    private static final String SOURCE_ATTRIBUTE = "source";

    private static final String DEFAULT_VALUE_ATTRIBUTE = "defaultValue";

    private final Environment environment;

    SpringPropertyAction(Environment environment) {
        this.environment = environment;
    }

    @Override
    public void begin(InterpretationContext context, String elementName, Attributes attributes) throws ActionException {
        String name = attributes.getValue(NAME_ATTRIBUTE);
        String source = attributes.getValue(SOURCE_ATTRIBUTE);
        Scope scope = ActionUtil.stringToScope(attributes.getValue(SCOPE_ATTRIBUTE));
        String defaultValue = attributes.getValue(DEFAULT_VALUE_ATTRIBUTE);
        if (OptionHelper.isEmpty(name) || OptionHelper.isEmpty(source)) {
            addError("The \"name\" and \"source\" attributes of <springProperty> must be set");
        }
        ActionUtil.setProperty(context, name, getValue(source, defaultValue), scope);
    }

    private String getValue(String source, String defaultValue) {
        if (this.environment == null) {
            addWarn("No Spring Environment available to resolve " + source);
            return defaultValue;
        }
        return this.environment.getProperty(source, defaultValue);
    }

    @Override
    public void end(InterpretationContext context, String name) throws ActionException {
    }

}
SpringPropertyAction继承了Action,它的主要功能就是允许从spring的environment中读取logback的配置;其getValue方法从environment中读取属性,然后通过ActionUtil.setProperty写入到InterpretationContext中

示例

<property name="LOGS" value="./logs" />
<springProperty scope="context" name="application.name" source="spring.application.name" />
<springProfile name="production">
    <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOGS}/${application.name}.log</file>
        <!-- configuration -->
    </appender>
</springProfile>
这里通过springProperty定义了application.name属性,其从spring environment读取key为spring.application.name的值作为application.name的值

小结

springboot的logback可以通过springProperty来引用spring environment中的属性在logback的配置文件中使用,其主要是通过SpringPropertyAction来实现的。


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...