logback.xml自定义标签节点

logback.xml自定义标签节点

问题

<?xml version="1.0" encoding="UTF-8" ?>
<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> <!-- Email -->
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </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}, 都可以解析到标签
     * 这里就可以自动 注入 <maskPattern/>标签
     * @param maskPattern
     */
    public void setMaskPattern(String maskPattern) {
        maskPatterns.add(maskPattern);
    }
}

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

像这里,我们定义了<maskPattern> 标签,然后要接收这个标签内的值 ,不难发现,只要我们在对应的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方法,就可以将自定义的标签内的值注入

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值