logback.xml自定义标签节点

logback.xml自定义标签节点

问题


<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="com.example.user.log.DataMaskingPatternLayout">
                <maskPattern>(\w+@\w+\.\w+)maskPattern> 
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%npattern>
            layout>
        encoder>
    appender>
    <root level="debug">
        <appender-ref ref="console"/>
    root>
configuration>

自定义layout

public class DataMaskingPatternLayout extends PatternLayout {
    private List<String> maskPatterns = new ArrayList<>();

    /**
     * 标签属性的 set{TagName},add{TagName}, 都可以解析到标签
     * 这里就可以自动 注入 标签
     * @param maskPattern
     */
    public void setMaskPattern(String maskPattern) {
        maskPatterns.add(maskPattern);
    }
}

今天的目的不是讨论自定义layout,而是如何接收自定义标签值

像这里,我们定义了 标签,然后要接收这个标签内的值 ,不难发现,只要我们在对应的java代码中增加这个标签属性名称的 set或者add 方法名就可以了,这就很奇怪了,是怎么实现的呢?

原理

  • 首先,logback会将自定义的结点封装成一个Action,而且是 ImplicitAction
  • 然后在运行时取出对应的Action, 如果是属性值方式,则 通过 NestedBasicPropertyIA 实现类
//NestedBasicPropertyIA.java

public void body(InterpretationContext ec, String body) {

    String finalBody = ec.subst(body);
    // get the action data object pushed in isApplicable() method call
    IADataForBasicProperty actionData = (IADataForBasicProperty) actionDataStack.peek();
    switch (actionData.aggregationType) {
        case AS_BASIC_PROPERTY:
            actionData.parentBean.setProperty(actionData.propertyName, finalBody);
            break;
        case AS_BASIC_PROPERTY_COLLECTION:
            actionData.parentBean.addBasicProperty(actionData.propertyName, finalBody);
            break;
        default:
            addError("Unexpected aggregationType " + actionData.aggregationType);
    }
}

交给 PropertySetter

public void setProperty(String name, String value) {
    if (value == null) {
        return;
    }
    Method setter = findSetterMethod(name);
    if (setter == null) {
        addWarn("No setter for property [" + name + "] in " + objClass.getName() + ".");
    } else {
        try {
            setProperty(setter, name, value);
        } catch (PropertySetterException ex) {
            addWarn("Failed to set property [" + name + "] to value \"" + value + "\". ", ex);
        }
    }
}

//找到属性名称的方法
private Method findSetterMethod(String name) {
    String propertyName = BeanUtil.toLowerCamelCase(name);
    return beanDescription.getSetter(propertyName);
}

public class BeanDescription {

    //propertyNameToGetter – map of property names to the associated getter. 
    //propertyNameToSetter – map of property names to the associated setter. 
    //propertyNameToAdder – map of property names to the associated adder.
	private final Class<?> clazz;

	private final Map<String, Method> propertyNameToGetter;

	private final Map<String, Method> propertyNameToSetter;

	private final Map<String, Method> propertyNameToAdder;
}

这里就可以发现,通过添加标签属性的 set或者add方法,就可以将自定义的标签内的值注入

你可能感兴趣的:(springmvc,logback)