You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2019/08/26 20:55:50 UTC

[logging-log4j2] branch master updated: [LOG4J2-2683] Rename PluginVisitor

This is an automated email from the ASF dual-hosted git repository.

mattsicker pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


The following commit(s) were added to refs/heads/master by this push:
     new 33009e1  [LOG4J2-2683] Rename PluginVisitor
33009e1 is described below

commit 33009e1163227a20b526ac04b9af79b90d439bf5
Author: Matt Sicker <bo...@gmail.com>
AuthorDate: Mon Aug 26 15:54:17 2019 -0500

    [LOG4J2-2683] Rename PluginVisitor
    
    This cleans up an unfortunately named set of classes from 2.x to more
    appropriately reflect their purpose. This also cleans up some of the
    related code.
---
 log4j-core/pom.xml                                 |   2 +-
 .../log4j/core/config/AbstractConfiguration.java   |   3 +-
 .../log4j/core/config/plugins/PluginAttribute.java |   4 +-
 .../config/plugins/PluginBuilderAttribute.java     |   4 +-
 .../core/config/plugins/PluginConfiguration.java   |   4 +-
 .../log4j/core/config/plugins/PluginElement.java   |   4 +-
 .../log4j/core/config/plugins/PluginNode.java      |   4 +-
 .../log4j/core/config/plugins/PluginValue.java     |   4 +-
 .../core/config/plugins/util/PluginBuilder.java    |  87 +++++++++--------
 .../plugins/visitors/AbstractPluginVisitor.java    |  45 +++++++++
 .../plugins/visitors/PluginAttributeVisitor.java   |  11 +--
 .../visitors/PluginBuilderAttributeVisitor.java    |  10 +-
 .../visitors/PluginConfigurationVisitor.java       |  13 +--
 .../plugins/visitors/PluginElementVisitor.java     |  23 ++---
 .../config/plugins/visitors/PluginNodeVisitor.java |   9 +-
 .../plugins/visitors/PluginValueVisitor.java       |  11 +--
 .../core/config/plugins/visitors/package-info.java |   4 +-
 log4j-plugins-java9/src/main/java/module-info.java |   2 +-
 .../log4j/plugins/{visitors => inject}/Dummy.java  |   4 +-
 .../logging/log4j/plugins/PluginAttribute.java     |   5 +-
 .../log4j/plugins/PluginBuilderAttribute.java      |   6 +-
 .../log4j/plugins/PluginBuilderFactory.java        |   1 +
 .../logging/log4j/plugins/PluginElement.java       |   5 +-
 .../apache/logging/log4j/plugins/PluginNode.java   |   5 +-
 .../apache/logging/log4j/plugins/PluginValue.java  |   5 +-
 .../AbstractPluginInjectionBuilder.java}           |  61 +++++++++---
 .../InjectionStrategy.java}                        |  16 ++--
 .../PluginAttributeBuilder.java}                   |  18 ++--
 .../PluginBuilderAttributeBuilder.java}            |  21 ++---
 .../PluginElementBuilder.java}                     |  28 +++---
 .../plugins/inject/PluginInjectionBuilder.java     | 105 +++++++++++++++++++++
 .../PluginNodeBuilder.java}                        |  16 ++--
 .../PluginValueBuilder.java}                       |  18 ++--
 .../plugins/{visitors => inject}/package-info.java |   9 +-
 .../log4j/plugins/visitors/PluginVisitor.java      |  82 ----------------
 .../log4j/plugins/visitors/PluginVisitors.java     |  56 -----------
 src/changes/changes.xml                            |   7 +-
 37 files changed, 364 insertions(+), 348 deletions(-)

diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index 2e15ca9..5f75511 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -469,7 +469,7 @@
               org.apache.logging.log4j.plugins.processor,
               org.apache.logging.log4j.plugins.util,
               org.apache.logging.log4j.plugins.validation,
-              org.apache.logging.log4j.plugins.visitors,
+              org.apache.logging.log4j.plugins.inject,
               *
             </Import-Package>
             <Bundle-Activator>org.apache.logging.log4j.core.osgi.Activator</Bundle-Activator>
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
index 747f24e..b3e1e7d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/AbstractConfiguration.java
@@ -63,6 +63,7 @@ import org.apache.logging.log4j.core.script.ScriptRef;
 import org.apache.logging.log4j.core.util.Constants;
 import org.apache.logging.log4j.core.time.internal.DummyNanoClock;
 import org.apache.logging.log4j.core.util.Loader;
+import org.apache.logging.log4j.plugins.inject.PluginInjectionBuilder;
 import org.apache.logging.log4j.util.NameUtil;
 import org.apache.logging.log4j.core.util.Source;
 import org.apache.logging.log4j.core.time.NanoClock;
@@ -970,7 +971,7 @@ public abstract class AbstractConfiguration extends AbstractFilterable implement
      * @param event the LogEvent that spurred the creation of this plugin
      * @return the created plugin object or {@code null} if there was an error setting it up.
      * @see org.apache.logging.log4j.core.config.plugins.util.PluginBuilder
-     * @see org.apache.logging.log4j.plugins.visitors.PluginVisitor
+     * @see org.apache.logging.log4j.plugins.inject.PluginInjectionBuilder
      * @see org.apache.logging.log4j.plugins.convert.TypeConverter
      */
     private Object createPluginObject(final PluginType<?> type, final Node node, final LogEvent event) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttribute.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttribute.java
index 03e78d8..a5595cf 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttribute.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginAttribute.java
@@ -16,7 +16,7 @@
  */
 package org.apache.logging.log4j.core.config.plugins;
 
-import org.apache.logging.log4j.plugins.PluginVisitorStrategy;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
 import org.apache.logging.log4j.core.config.plugins.visitors.PluginAttributeVisitor;
 import org.apache.logging.log4j.util.Strings;
 
@@ -33,7 +33,7 @@ import java.lang.annotation.*;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginAttributeVisitor.class)
+@InjectionStrategy(PluginAttributeVisitor.class)
 public @interface PluginAttribute {
 
     /**
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilderAttribute.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilderAttribute.java
index e34369f..584d5f8 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilderAttribute.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginBuilderAttribute.java
@@ -17,7 +17,7 @@
 
 package org.apache.logging.log4j.core.config.plugins;
 
-import org.apache.logging.log4j.plugins.PluginVisitorStrategy;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
 import org.apache.logging.log4j.core.config.plugins.visitors.PluginBuilderAttributeVisitor;
 import org.apache.logging.log4j.util.Strings;
 
@@ -30,7 +30,7 @@ import java.lang.annotation.*;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginBuilderAttributeVisitor.class)
+@InjectionStrategy(PluginBuilderAttributeVisitor.class)
 public @interface PluginBuilderAttribute {
 
     /**
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.java
index f6aa202..e941388 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.java
@@ -23,7 +23,7 @@ import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
 import org.apache.logging.log4j.core.config.plugins.visitors.PluginConfigurationVisitor;
-import org.apache.logging.log4j.plugins.PluginVisitorStrategy;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
 
 /**
  * Identifies a parameter or field as a Configuration.
@@ -32,7 +32,7 @@ import org.apache.logging.log4j.plugins.PluginVisitorStrategy;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginConfigurationVisitor.class)
+@InjectionStrategy(PluginConfigurationVisitor.class)
 public @interface PluginConfiguration {
     // empty
 }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java
index 9c1156b..81c5a47 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginElement.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.config.plugins;
 
 import org.apache.logging.log4j.core.config.plugins.visitors.PluginElementVisitor;
-import org.apache.logging.log4j.plugins.PluginVisitorStrategy;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
 
 import java.lang.annotation.*;
 
@@ -28,7 +28,7 @@ import java.lang.annotation.*;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginElementVisitor.class)
+@InjectionStrategy(PluginElementVisitor.class)
 public @interface PluginElement {
 
     /**
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java
index b359253..3411a12 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginNode.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.config.plugins;
 
 import org.apache.logging.log4j.core.config.plugins.visitors.PluginNodeVisitor;
-import org.apache.logging.log4j.plugins.PluginVisitorStrategy;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
 
 import java.lang.annotation.*;
 
@@ -28,7 +28,7 @@ import java.lang.annotation.*;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginNodeVisitor.class)
+@InjectionStrategy(PluginNodeVisitor.class)
 public @interface PluginNode {
     // empty
 }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java
index 4b12c77..0a93acb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/PluginValue.java
@@ -17,7 +17,7 @@
 package org.apache.logging.log4j.core.config.plugins;
 
 import org.apache.logging.log4j.core.config.plugins.visitors.PluginValueVisitor;
-import org.apache.logging.log4j.plugins.PluginVisitorStrategy;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
 
 
 import java.lang.annotation.*;
@@ -32,7 +32,7 @@ import java.lang.annotation.*;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginValueVisitor.class)
+@InjectionStrategy(PluginValueVisitor.class)
 public @interface PluginValue {
 
     String value();
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
index e05523a..877c537 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/util/PluginBuilder.java
@@ -17,20 +17,6 @@
 
 package org.apache.logging.log4j.core.config.plugins.util;
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AccessibleObject;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.function.Function;
-
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
@@ -40,17 +26,31 @@ import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.PluginAliases;
 import org.apache.logging.log4j.plugins.PluginBuilderFactory;
 import org.apache.logging.log4j.plugins.PluginFactory;
+import org.apache.logging.log4j.plugins.inject.PluginInjectionBuilder;
 import org.apache.logging.log4j.plugins.util.Builder;
 import org.apache.logging.log4j.plugins.util.PluginType;
 import org.apache.logging.log4j.plugins.util.TypeUtil;
 import org.apache.logging.log4j.plugins.validation.ConstraintValidator;
 import org.apache.logging.log4j.plugins.validation.ConstraintValidators;
-import org.apache.logging.log4j.plugins.visitors.PluginVisitor;
-import org.apache.logging.log4j.plugins.visitors.PluginVisitors;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.ReflectionUtil;
 import org.apache.logging.log4j.util.StringBuilders;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+
 /**
  * Builder class to instantiate and configure a Plugin object using a PluginFactory method or PluginBuilderFactory
  * builder class.
@@ -189,18 +189,20 @@ public class PluginBuilder implements Builder<Object> {
                         a instanceof org.apache.logging.log4j.core.config.plugins.PluginAliases) {
                     continue; // already processed
                 }
-                final PluginVisitor<? extends Annotation, Configuration> visitor =
-                    PluginVisitors.findVisitor(a.annotationType());
-                if (visitor != null) {
-                    final Object value = visitor.setAliases(aliases)
-                        .setAnnotation(a)
-                        .setConversionType(field.getType())
-                        .setMember(field)
-                        .visit(configuration, node, substitutor, log);
-                    // don't overwrite default values if the visitor gives us no value to inject
-                    if (value != null) {
-                        field.set(target, value);
-                    }
+                final Object value = PluginInjectionBuilder.findBuilderForInjectionStrategy(a.annotationType())
+                        .flatMap(b -> Optional.ofNullable(b
+                                .withAliases(aliases)
+                                .withAnnotation(a)
+                                .withConfiguration(configuration)
+                                .withConfigurationNode(node)
+                                .withConversionType(field.getType())
+                                .withDebugLog(log)
+                                .withMember(field)
+                                .withStringSubstitutionStrategy(substitutor)
+                                .build()))
+                        .orElse(null);
+                if (value != null) {
+                    field.set(target, value);
                 }
             }
             final Collection<ConstraintValidator<?>> validators =
@@ -262,24 +264,27 @@ public class PluginBuilder implements Builder<Object> {
         for (int i = 0; i < annotations.length; i++) {
             log.append(log.length() == 0 ? factory.getName() + "(" : ", ");
             final String[] aliases = extractPluginAliases(annotations[i]);
+            final Class<?> conversionType = types[i];
             for (final Annotation a : annotations[i]) {
                 if (a instanceof PluginAliases ||
                         a instanceof org.apache.logging.log4j.core.config.plugins.PluginAliases) {
                     continue; // already processed
                 }
-                final PluginVisitor<? extends Annotation, Configuration> visitor = PluginVisitors.findVisitor(
-                    a.annotationType());
-
-                if (visitor != null) {
-                    final Object value = visitor.setAliases(aliases)
-                        .setAnnotation(a)
-                        .setConversionType(types[i])
-                        .setMember(factory)
-                        .visit(configuration, node, substitutor, log);
-                    // don't overwrite existing values if the visitor gives us no value to inject
-                    if (value != null) {
-                        args[i] = value;
-                    }
+                final Object value = PluginInjectionBuilder.findBuilderForInjectionStrategy(a.annotationType())
+                        .flatMap(b -> Optional.ofNullable(b
+                                .withAliases(aliases)
+                                .withAnnotation(a)
+                                .withConfiguration(configuration)
+                                .withConfigurationNode(node)
+                                .withConversionType(conversionType)
+                                .withDebugLog(log)
+                                .withMember(factory)
+                                .withStringSubstitutionStrategy(substitutor)
+                                .build()))
+                        .orElse(null);
+                // don't overwrite existing values if the builder gives us no value to inject
+                if (value != null) {
+                    args[i] = value;
                 }
             }
             final Collection<ConstraintValidator<?>> validators =
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/AbstractPluginVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/AbstractPluginVisitor.java
new file mode 100644
index 0000000..266a3e0
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/AbstractPluginVisitor.java
@@ -0,0 +1,45 @@
+package org.apache.logging.log4j.core.config.plugins.visitors;
+
+import org.apache.logging.log4j.plugins.Node;
+import org.apache.logging.log4j.plugins.inject.AbstractPluginInjectionBuilder;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
+import java.util.function.Function;
+
+abstract class AbstractPluginVisitor<Ann extends Annotation, Cfg> extends AbstractPluginInjectionBuilder<Ann, Cfg> {
+
+    AbstractPluginVisitor(final Class<Ann> clazz) {
+        super(clazz);
+    }
+
+    public AbstractPluginVisitor<Ann, Cfg> setAnnotation(final Annotation annotation) {
+        if (clazz.isInstance(annotation)) {
+            withAnnotation(clazz.cast(annotation));
+        }
+        return this;
+    }
+
+    public AbstractPluginVisitor<Ann, Cfg> setAliases(final String... aliases) {
+        withAliases(aliases);
+        return this;
+    }
+
+    public AbstractPluginVisitor<Ann, Cfg> setConversionType(final Class<?> conversionType) {
+        withConversionType(conversionType);
+        return this;
+    }
+
+    public AbstractPluginVisitor<Ann, Cfg> setMember(final Member member) {
+        withMember(member);
+        return this;
+    }
+
+    public Object visit(final Cfg configuration, final Node node, final Function<String, String> substitutor, final StringBuilder log) {
+        return this.withConfiguration(configuration)
+                .withConfigurationNode(node)
+                .withStringSubstitutionStrategy(substitutor)
+                .withDebugLog(log)
+                .build();
+    }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginAttributeVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginAttributeVisitor.java
index a24ded7..f8e30c2 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginAttributeVisitor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginAttributeVisitor.java
@@ -16,9 +16,7 @@
  */
 package org.apache.logging.log4j.core.config.plugins.visitors;
 
-import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
-import org.apache.logging.log4j.plugins.visitors.AbstractPluginVisitor;
 import org.apache.logging.log4j.util.NameUtil;
 import org.apache.logging.log4j.util.StringBuilders;
 
@@ -34,16 +32,15 @@ public class PluginAttributeVisitor extends AbstractPluginVisitor<PluginAttribut
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         final String name = this.annotation.value();
         final Map<String, String> attributes = node.getAttributes();
         final String rawValue = removeAttributeValue(attributes, name, this.aliases);
-        final String replacedValue = substitutor.apply(rawValue);
-        final Object defaultValue = findDefaultValue(substitutor);
+        final String replacedValue = stringSubstitutionStrategy.apply(rawValue);
+        final Object defaultValue = findDefaultValue(stringSubstitutionStrategy);
         final Object value = convert(replacedValue, defaultValue);
         final Object debugValue = this.annotation.sensitive() ? NameUtil.md5(value + this.getClass().getName()) : value;
-        StringBuilders.appendKeyDqValue(log, name, debugValue);
+        StringBuilders.appendKeyDqValue(debugLog, name, debugValue);
         return value;
     }
 
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginBuilderAttributeVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginBuilderAttributeVisitor.java
index 7c5ed21..6c7f6b0 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginBuilderAttributeVisitor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginBuilderAttributeVisitor.java
@@ -18,13 +18,10 @@
 package org.apache.logging.log4j.core.config.plugins.visitors;
 
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
-import org.apache.logging.log4j.plugins.Node;
-import org.apache.logging.log4j.plugins.visitors.AbstractPluginVisitor;
 import org.apache.logging.log4j.util.NameUtil;
 import org.apache.logging.log4j.util.StringBuilders;
 
 import java.util.Map;
-import java.util.function.Function;
 
 /**
  * @deprecated Provided for support for PluginBuilderAttribute.
@@ -36,16 +33,15 @@ public class PluginBuilderAttributeVisitor extends AbstractPluginVisitor<PluginB
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         final String overridden = this.annotation.value();
         final String name = overridden.isEmpty() ? this.member.getName() : overridden;
         final Map<String, String> attributes = node.getAttributes();
         final String rawValue = removeAttributeValue(attributes, name, this.aliases);
-        final String replacedValue = substitutor.apply(rawValue);
+        final String replacedValue = stringSubstitutionStrategy.apply(rawValue);
         final Object value = convert(replacedValue, null);
         final Object debugValue = this.annotation.sensitive() ? NameUtil.md5(value + this.getClass().getName()) : value;
-        StringBuilders.appendKeyDqValue(log, name, debugValue);
+        StringBuilders.appendKeyDqValue(debugLog, name, debugValue);
         return value;
     }
 }
\ No newline at end of file
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginConfigurationVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginConfigurationVisitor.java
index 4ff709f..20976c7 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginConfigurationVisitor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginConfigurationVisitor.java
@@ -19,10 +19,6 @@ package org.apache.logging.log4j.core.config.plugins.visitors;
 
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
-import org.apache.logging.log4j.plugins.visitors.AbstractPluginVisitor;
-import org.apache.logging.log4j.plugins.Node;
-
-import java.util.function.Function;
 
 /**
  * PluginVisitor implementation for {@link PluginConfiguration}.
@@ -33,17 +29,16 @@ public class PluginConfigurationVisitor extends AbstractPluginVisitor<PluginConf
     }
 
     @Override
-    public Object visit(final Configuration configuration, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         if (this.conversionType.isInstance(configuration)) {
-            log.append("Configuration");
+            debugLog.append("Configuration");
             if (configuration.getName() != null) {
-                log.append('(').append(configuration.getName()).append(')');
+                debugLog.append('(').append(configuration.getName()).append(')');
             }
             return configuration;
         }
         LOGGER.warn("Variable annotated with @PluginConfiguration is not compatible with type {}.",
-            configuration.getClass());
+                configuration.getClass());
         return null;
     }
 }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginElementVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginElementVisitor.java
index 1d362f0..de80831 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginElementVisitor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginElementVisitor.java
@@ -20,14 +20,12 @@ package org.apache.logging.log4j.core.config.plugins.visitors;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
 import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.util.PluginType;
-import org.apache.logging.log4j.plugins.visitors.AbstractPluginVisitor;
 
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import java.util.function.Function;
 
 /**
  *  @deprecated Provided to support legacy plugins.
@@ -38,21 +36,20 @@ public class PluginElementVisitor extends AbstractPluginVisitor<PluginElement, O
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         final String name = this.annotation.value();
         if (this.conversionType.isArray()) {
             setConversionType(this.conversionType.getComponentType());
             final List<Object> values = new ArrayList<>();
             final Collection<Node> used = new ArrayList<>();
-            log.append("={");
+            debugLog.append("={");
             boolean first = true;
             for (final Node child : node.getChildren()) {
                 final PluginType<?> childType = child.getType();
                 if (name.equalsIgnoreCase(childType.getElementName()) ||
-                    this.conversionType.isAssignableFrom(childType.getPluginClass())) {
+                        this.conversionType.isAssignableFrom(childType.getPluginClass())) {
                     if (!first) {
-                        log.append(", ");
+                        debugLog.append(", ");
                     }
                     first = false;
                     used.add(child);
@@ -62,19 +59,19 @@ public class PluginElementVisitor extends AbstractPluginVisitor<PluginElement, O
                         continue;
                     }
                     if (childObject.getClass().isArray()) {
-                        log.append(Arrays.toString((Object[]) childObject)).append('}');
+                        debugLog.append(Arrays.toString((Object[]) childObject)).append('}');
                         node.getChildren().removeAll(used);
                         return childObject;
                     }
-                    log.append(child.toString());
+                    debugLog.append(child.toString());
                     values.add(childObject);
                 }
             }
-            log.append('}');
+            debugLog.append('}');
             // note that we need to return an empty array instead of null if the types are correct
             if (!values.isEmpty() && !this.conversionType.isAssignableFrom(values.get(0).getClass())) {
                 LOGGER.error("Attempted to assign attribute {} to list of type {} which is incompatible with {}.",
-                    name, values.get(0).getClass(), this.conversionType);
+                        name, values.get(0).getClass(), this.conversionType);
                 return null;
             }
             node.getChildren().removeAll(used);
@@ -87,10 +84,10 @@ public class PluginElementVisitor extends AbstractPluginVisitor<PluginElement, O
         }
         final Node namedNode = findNamedNode(name, node.getChildren());
         if (namedNode == null) {
-            log.append(name).append("=null");
+            debugLog.append(name).append("=null");
             return null;
         }
-        log.append(namedNode.getName()).append('(').append(namedNode.toString()).append(')');
+        debugLog.append(namedNode.getName()).append('(').append(namedNode.toString()).append(')');
         node.getChildren().remove(namedNode);
         return namedNode.getObject();
     }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginNodeVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginNodeVisitor.java
index 8fa7d6c..57c0d89 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginNodeVisitor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginNodeVisitor.java
@@ -18,10 +18,6 @@
 package org.apache.logging.log4j.core.config.plugins.visitors;
 
 import org.apache.logging.log4j.core.config.plugins.PluginNode;
-import org.apache.logging.log4j.plugins.Node;
-import org.apache.logging.log4j.plugins.visitors.AbstractPluginVisitor;
-
-import java.util.function.Function;
 
 /**
  *  @deprecated Provided to support legacy plugins.
@@ -32,10 +28,9 @@ public class PluginNodeVisitor extends AbstractPluginVisitor<PluginNode, Object>
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         if (this.conversionType.isInstance(node)) {
-            log.append("Node=").append(node.getName());
+            debugLog.append("Node=").append(node.getName());
             return node;
         }
         LOGGER.warn("Variable annotated with @PluginNode is not compatible with the type {}.", node.getClass());
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginValueVisitor.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginValueVisitor.java
index 13c0232..9600514 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginValueVisitor.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/PluginValueVisitor.java
@@ -18,13 +18,9 @@
 package org.apache.logging.log4j.core.config.plugins.visitors;
 
 import org.apache.logging.log4j.core.config.plugins.PluginValue;
-import org.apache.logging.log4j.plugins.Node;
-import org.apache.logging.log4j.plugins.visitors.AbstractPluginVisitor;
 import org.apache.logging.log4j.util.StringBuilders;
 import org.apache.logging.log4j.util.Strings;
 
-import java.util.function.Function;
-
 /**
  *  @deprecated Provided to support legacy plugins.
  */
@@ -34,8 +30,7 @@ public class PluginValueVisitor extends AbstractPluginVisitor<PluginValue, Objec
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         final String name = this.annotation.value();
         final String elementValue = node.getValue();
         final String attributeValue = node.getAttributes().get("value");
@@ -50,8 +45,8 @@ public class PluginValueVisitor extends AbstractPluginVisitor<PluginValue, Objec
         } else {
             rawValue = removeAttributeValue(node.getAttributes(), "value");
         }
-        final String value = substitutor.apply(rawValue);
-        StringBuilders.appendKeyDqValue(log, name, value);
+        final String value = stringSubstitutionStrategy.apply(rawValue);
+        StringBuilders.appendKeyDqValue(debugLog, name, value);
         return value;
     }
 }
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/package-info.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/package-info.java
index eb5ed62..04badd1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/package-info.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/config/plugins/visitors/package-info.java
@@ -17,8 +17,8 @@
 
 /**
  * Visitor classes for extracting values from a Configuration or Node corresponding to a plugin annotation.
- * Visitor implementations must implement {@link org.apache.logging.log4j.plugins.visitors.PluginVisitor},
+ * Visitor implementations must implement {@link org.apache.logging.log4j.plugins.inject.PluginInjectionBuilder},
  * and the corresponding annotation must be annotated with
- * {@link org.apache.logging.log4j.plugins.PluginVisitorStrategy}.
+ * {@link org.apache.logging.log4j.plugins.inject.InjectionStrategy}.
  */
 package org.apache.logging.log4j.core.config.plugins.visitors;
diff --git a/log4j-plugins-java9/src/main/java/module-info.java b/log4j-plugins-java9/src/main/java/module-info.java
index 9802622..801ee80 100644
--- a/log4j-plugins-java9/src/main/java/module-info.java
+++ b/log4j-plugins-java9/src/main/java/module-info.java
@@ -20,7 +20,7 @@ module org.apache.logging.log4j.plugins {
     exports org.apache.logging.log4j.plugins.processor;
     exports org.apache.logging.log4j.plugins.util;
     exports org.apache.logging.log4j.plugins.validation;
-    exports org.apache.logging.log4j.plugins.visitors;
+    exports org.apache.logging.log4j.plugins.inject;
 
     uses org.apache.logging.log4j.plugins.processor.PluginService;
 }
diff --git a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/visitors/Dummy.java b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/inject/Dummy.java
similarity index 90%
rename from log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/visitors/Dummy.java
rename to log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/inject/Dummy.java
index 5596338..68f4aa2 100644
--- a/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/visitors/Dummy.java
+++ b/log4j-plugins-java9/src/main/java/org/apache/logging/log4j/plugins/inject/Dummy.java
@@ -14,11 +14,11 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-package org.apache.logging.log4j.plugins.visitors;
+package org.apache.logging.log4j.plugins.inject;
 
 /**
  * This is a dummy class and is only here to allow module-info.java to compile. It will not
- * be copied into the log4j-api module.
+ * be copied into the log4j-plugins module.
  */
 public class Dummy {
 }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginAttribute.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginAttribute.java
index b9d4684..efc769a 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginAttribute.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginAttribute.java
@@ -16,7 +16,8 @@
  */
 package org.apache.logging.log4j.plugins;
 
-import org.apache.logging.log4j.plugins.visitors.PluginAttributeVisitor;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
+import org.apache.logging.log4j.plugins.inject.PluginAttributeBuilder;
 import org.apache.logging.log4j.util.Strings;
 
 import java.lang.annotation.Documented;
@@ -35,7 +36,7 @@ import java.lang.annotation.Target;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginAttributeVisitor.class)
+@InjectionStrategy(PluginAttributeBuilder.class)
 public @interface PluginAttribute {
 
     /**
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginBuilderAttribute.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginBuilderAttribute.java
index ed22bb9..36e6ff2 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginBuilderAttribute.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginBuilderAttribute.java
@@ -17,7 +17,8 @@
 
 package org.apache.logging.log4j.plugins;
 
-import org.apache.logging.log4j.plugins.visitors.PluginBuilderAttributeVisitor;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
+import org.apache.logging.log4j.plugins.inject.PluginBuilderAttributeBuilder;
 import org.apache.logging.log4j.util.Strings;
 
 import java.lang.annotation.Documented;
@@ -32,7 +33,8 @@ import java.lang.annotation.Target;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.TYPE})
-@PluginVisitorStrategy(PluginBuilderAttributeVisitor.class)
+@InjectionStrategy(PluginBuilderAttributeBuilder.class)
+// TODO: this annotation can be combined with @PluginAttribute along with giving it a default value
 public @interface PluginBuilderAttribute {
 
     /**
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginBuilderFactory.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginBuilderFactory.java
index 035b025..4d15caa 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginBuilderFactory.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginBuilderFactory.java
@@ -29,6 +29,7 @@ import java.lang.annotation.Target;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
+// TODO: this can be combined with @PluginFactory as differentiating them by method signature is obvious
 public @interface PluginBuilderFactory {
     // empty
 }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginElement.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginElement.java
index 6cfb6fa..919d138 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginElement.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginElement.java
@@ -16,7 +16,8 @@
  */
 package org.apache.logging.log4j.plugins;
 
-import org.apache.logging.log4j.plugins.visitors.PluginElementVisitor;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
+import org.apache.logging.log4j.plugins.inject.PluginElementBuilder;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
@@ -30,7 +31,7 @@ import java.lang.annotation.Target;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginElementVisitor.class)
+@InjectionStrategy(PluginElementBuilder.class)
 public @interface PluginElement {
 
     /**
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginNode.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginNode.java
index b172268..2f5cef3 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginNode.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginNode.java
@@ -16,7 +16,8 @@
  */
 package org.apache.logging.log4j.plugins;
 
-import org.apache.logging.log4j.plugins.visitors.PluginNodeVisitor;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
+import org.apache.logging.log4j.plugins.inject.PluginNodeBuilder;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
@@ -30,7 +31,7 @@ import java.lang.annotation.Target;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginNodeVisitor.class)
+@InjectionStrategy(PluginNodeBuilder.class)
 public @interface PluginNode {
     // empty
 }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginValue.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginValue.java
index 31e5a23..84c4385 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginValue.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginValue.java
@@ -16,7 +16,8 @@
  */
 package org.apache.logging.log4j.plugins;
 
-import org.apache.logging.log4j.plugins.visitors.PluginValueVisitor;
+import org.apache.logging.log4j.plugins.inject.InjectionStrategy;
+import org.apache.logging.log4j.plugins.inject.PluginValueBuilder;
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
@@ -33,7 +34,7 @@ import java.lang.annotation.Target;
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.PARAMETER, ElementType.FIELD})
-@PluginVisitorStrategy(PluginValueVisitor.class)
+@InjectionStrategy(PluginValueBuilder.class)
 public @interface PluginValue {
 
     String value();
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/AbstractPluginVisitor.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/AbstractPluginInjectionBuilder.java
similarity index 68%
rename from log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/AbstractPluginVisitor.java
rename to log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/AbstractPluginInjectionBuilder.java
index 01e1e66..569dcef 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/AbstractPluginVisitor.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/AbstractPluginInjectionBuilder.java
@@ -15,9 +15,10 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.plugins.visitors;
+package org.apache.logging.log4j.plugins.inject;
 
 import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.convert.TypeConverters;
 import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.Strings;
@@ -26,14 +27,15 @@ import java.lang.annotation.Annotation;
 import java.lang.reflect.Member;
 import java.util.Map;
 import java.util.Objects;
+import java.util.function.Function;
 
 /**
- * Base class for PluginVisitor implementations. Provides convenience methods as well as all method implementations
- * other than the {@code visit} method.
+ * Base class for InjectionStrategyBuilder implementations. Provides fields and setters for the builder leaving only
+ * {@link PluginInjectionBuilder#build()} to be implemented.
  *
- * @param <A> the Plugin annotation type.
+ * @param <Ann> the Plugin annotation type.
  */
-public abstract class AbstractPluginVisitor<A extends Annotation, T> implements PluginVisitor<A, T> {
+public abstract class AbstractPluginInjectionBuilder<Ann extends Annotation, Cfg> implements PluginInjectionBuilder<Ann, Cfg> {
 
     /** Status logger. */
     protected static final Logger LOGGER = StatusLogger.getLogger();
@@ -41,11 +43,11 @@ public abstract class AbstractPluginVisitor<A extends Annotation, T> implements
     /**
      * 
      */
-    protected final Class<A> clazz;
+    protected final Class<Ann> clazz;
     /**
      * 
      */
-    protected A annotation;
+    protected Ann annotation;
     /**
      * 
      */
@@ -59,43 +61,74 @@ public abstract class AbstractPluginVisitor<A extends Annotation, T> implements
      */
     protected Member member;
 
+    protected Cfg configuration;
+
+    protected Node node;
+
+    protected Function<String, String> stringSubstitutionStrategy;
+
+    protected StringBuilder debugLog;
+
     /**
      * This constructor must be overridden by implementation classes as a no-arg constructor.
      *
      * @param clazz the annotation class this PluginVisitor is for.
      */
-    protected AbstractPluginVisitor(final Class<A> clazz) {
+    protected AbstractPluginInjectionBuilder(final Class<Ann> clazz) {
         this.clazz = clazz;
     }
 
-    @SuppressWarnings("unchecked")
     @Override
-    public PluginVisitor<A, T> setAnnotation(final Annotation anAnnotation) {
+    public PluginInjectionBuilder<Ann, Cfg> withAnnotation(final Annotation anAnnotation) {
         final Annotation a = Objects.requireNonNull(anAnnotation, "No annotation was provided");
         if (this.clazz.isInstance(a)) {
-            this.annotation = (A) a;
+            this.annotation = clazz.cast(a);
         }
         return this;
     }
 
     @Override
-    public PluginVisitor<A, T> setAliases(final String... someAliases) {
+    public PluginInjectionBuilder<Ann, Cfg> withAliases(final String... someAliases) {
         this.aliases = someAliases;
         return this;
     }
 
     @Override
-    public PluginVisitor<A, T> setConversionType(final Class<?> aConversionType) {
+    public PluginInjectionBuilder<Ann, Cfg> withConversionType(final Class<?> aConversionType) {
         this.conversionType = Objects.requireNonNull(aConversionType, "No conversion type class was provided");
         return this;
     }
 
     @Override
-    public PluginVisitor<A, T> setMember(final Member aMember) {
+    public PluginInjectionBuilder<Ann, Cfg> withMember(final Member aMember) {
         this.member = aMember;
         return this;
     }
 
+    @Override
+    public PluginInjectionBuilder<Ann, Cfg> withConfiguration(final Cfg aConfiguration) {
+        this.configuration = aConfiguration;
+        return this;
+    }
+
+    @Override
+    public PluginInjectionBuilder<Ann, Cfg> withStringSubstitutionStrategy(final Function<String, String> aStringSubstitutionStrategy) {
+        this.stringSubstitutionStrategy = aStringSubstitutionStrategy;
+        return this;
+    }
+
+    @Override
+    public PluginInjectionBuilder<Ann, Cfg> withDebugLog(final StringBuilder aDebugLog) {
+        this.debugLog = aDebugLog;
+        return this;
+    }
+
+    @Override
+    public PluginInjectionBuilder<Ann, Cfg> withConfigurationNode(final Node aNode) {
+        this.node = aNode;
+        return this;
+    }
+
     /**
      * Removes an Entry from a given Map using a key name and aliases for that key. Keys are case-insensitive.
      *
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginVisitorStrategy.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/InjectionStrategy.java
similarity index 67%
rename from log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginVisitorStrategy.java
rename to log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/InjectionStrategy.java
index 093cc50..ac3c633 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/PluginVisitorStrategy.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/InjectionStrategy.java
@@ -15,9 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.plugins;
-
-import org.apache.logging.log4j.plugins.visitors.PluginVisitor;
+package org.apache.logging.log4j.plugins.inject;
 
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Documented;
@@ -28,17 +26,17 @@ import java.lang.annotation.Target;
 
 /**
  * Meta-annotation to denote the class name to use that implements
- * {@link org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitor} for the annotated annotation.
+ * {@link PluginInjectionBuilder} for the annotated annotation.
  */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.ANNOTATION_TYPE)
-public @interface PluginVisitorStrategy {
+public @interface InjectionStrategy {
 
     /**
-     * The class to use that implements {@link org.apache.logging.log4j.core.config.plugins.visitors.PluginVisitor}
-     * for the given annotation. The generic type in {@code PluginVisitor} should match the annotation this annotation
-     * is applied to.
+     * The class to use that implements {@link PluginInjectionBuilder}
+     * for the given annotation. The generic annotation type in {@code PluginInjectionBuilder} should match the
+     * annotation this annotation is applied to.
      */
-    Class<? extends PluginVisitor<? extends Annotation, ?>> value();
+    Class<? extends PluginInjectionBuilder<? extends Annotation, ?>> value();
 }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginAttributeVisitor.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginAttributeBuilder.java
similarity index 82%
rename from log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginAttributeVisitor.java
rename to log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginAttributeBuilder.java
index fbd28b9..23566dd 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginAttributeVisitor.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginAttributeBuilder.java
@@ -15,9 +15,8 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.plugins.visitors;
+package org.apache.logging.log4j.plugins.inject;
 
-import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.PluginAttribute;
 import org.apache.logging.log4j.util.NameUtil;
 import org.apache.logging.log4j.util.StringBuilders;
@@ -26,24 +25,23 @@ import java.util.Map;
 import java.util.function.Function;
 
 /**
- * PluginVisitor implementation for {@link PluginAttribute}.
+ * PluginInjectionBuilder implementation for {@link PluginAttribute}.
  */
-public class PluginAttributeVisitor extends AbstractPluginVisitor<PluginAttribute, Object> {
-    public PluginAttributeVisitor() {
+public class PluginAttributeBuilder extends AbstractPluginInjectionBuilder<PluginAttribute, Object> {
+    public PluginAttributeBuilder() {
         super(PluginAttribute.class);
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         final String name = this.annotation.value();
         final Map<String, String> attributes = node.getAttributes();
         final String rawValue = removeAttributeValue(attributes, name, this.aliases);
-        final String replacedValue = substitutor.apply(rawValue);
-        final Object defaultValue = findDefaultValue(substitutor);
+        final String replacedValue = stringSubstitutionStrategy.apply(rawValue);
+        final Object defaultValue = findDefaultValue(stringSubstitutionStrategy);
         final Object value = convert(replacedValue, defaultValue);
         final Object debugValue = this.annotation.sensitive() ? NameUtil.md5(value + this.getClass().getName()) : value;
-        StringBuilders.appendKeyDqValue(log, name, debugValue);
+        StringBuilders.appendKeyDqValue(debugLog, name, debugValue);
         return value;
     }
 
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginBuilderAttributeVisitor.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginBuilderAttributeBuilder.java
similarity index 64%
rename from log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginBuilderAttributeVisitor.java
rename to log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginBuilderAttributeBuilder.java
index 398ff1c..28e6843 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginBuilderAttributeVisitor.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginBuilderAttributeBuilder.java
@@ -15,40 +15,35 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.plugins.visitors;
+package org.apache.logging.log4j.plugins.inject;
 
-import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.util.NameUtil;
 import org.apache.logging.log4j.util.StringBuilders;
 
 import java.util.Map;
-import java.util.function.Function;
 
 /**
- * PluginVisitor for PluginBuilderAttribute. If {@code null} is returned for the
- * {@link #visit(org.apache.logging.log4j.core.config.Configuration, org.apache.logging.log4j.plugins.Node, org.apache.logging.log4j.core.LogEvent, StringBuilder)}
+ * PluginInjectionBuilder for PluginBuilderAttribute. If {@code null} is returned for the
+ * {@link PluginInjectionBuilder#build()}}
  * method, then the default value of the field should remain untouched.
- *
- * @see org.apache.logging.log4j.core.config.plugins.util.PluginBuilder
  */
-public class PluginBuilderAttributeVisitor extends AbstractPluginVisitor<PluginBuilderAttribute, Object> {
+public class PluginBuilderAttributeBuilder extends AbstractPluginInjectionBuilder<PluginBuilderAttribute, Object> {
 
-    public PluginBuilderAttributeVisitor() {
+    public PluginBuilderAttributeBuilder() {
         super(PluginBuilderAttribute.class);
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         final String overridden = this.annotation.value();
         final String name = overridden.isEmpty() ? this.member.getName() : overridden;
         final Map<String, String> attributes = node.getAttributes();
         final String rawValue = removeAttributeValue(attributes, name, this.aliases);
-        final String replacedValue = substitutor.apply(rawValue);
+        final String replacedValue = stringSubstitutionStrategy.apply(rawValue);
         final Object value = convert(replacedValue, null);
         final Object debugValue = this.annotation.sensitive() ? NameUtil.md5(value + this.getClass().getName()) : value;
-        StringBuilders.appendKeyDqValue(log, name, debugValue);
+        StringBuilders.appendKeyDqValue(debugLog, name, debugValue);
         return value;
     }
 }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginElementVisitor.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginElementBuilder.java
similarity index 81%
rename from log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginElementVisitor.java
rename to log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginElementBuilder.java
index f8197f1..7f3939a 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginElementVisitor.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginElementBuilder.java
@@ -15,7 +15,7 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.plugins.visitors;
+package org.apache.logging.log4j.plugins.inject;
 
 import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.PluginElement;
@@ -26,32 +26,30 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
-import java.util.function.Function;
 
 /**
- * PluginVisitor implementation for {@link PluginElement}. Supports arrays as well as singular values.
+ * PluginInjectionBuilder implementation for {@link PluginElement}. Supports arrays as well as singular values.
  */
-public class PluginElementVisitor extends AbstractPluginVisitor<PluginElement, Object> {
-    public PluginElementVisitor() {
+public class PluginElementBuilder extends AbstractPluginInjectionBuilder<PluginElement, Object> {
+    public PluginElementBuilder() {
         super(PluginElement.class);
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         final String name = this.annotation.value();
         if (this.conversionType.isArray()) {
-            setConversionType(this.conversionType.getComponentType());
+            withConversionType(this.conversionType.getComponentType());
             final List<Object> values = new ArrayList<>();
             final Collection<Node> used = new ArrayList<>();
-            log.append("={");
+            debugLog.append("={");
             boolean first = true;
             for (final Node child : node.getChildren()) {
                 final PluginType<?> childType = child.getType();
                 if (name.equalsIgnoreCase(childType.getElementName()) ||
                     this.conversionType.isAssignableFrom(childType.getPluginClass())) {
                     if (!first) {
-                        log.append(", ");
+                        debugLog.append(", ");
                     }
                     first = false;
                     used.add(child);
@@ -61,15 +59,15 @@ public class PluginElementVisitor extends AbstractPluginVisitor<PluginElement, O
                         continue;
                     }
                     if (childObject.getClass().isArray()) {
-                        log.append(Arrays.toString((Object[]) childObject)).append('}');
+                        debugLog.append(Arrays.toString((Object[]) childObject)).append('}');
                         node.getChildren().removeAll(used);
                         return childObject;
                     }
-                    log.append(child.toString());
+                    debugLog.append(child.toString());
                     values.add(childObject);
                 }
             }
-            log.append('}');
+            debugLog.append('}');
             // note that we need to return an empty array instead of null if the types are correct
             if (!values.isEmpty() && !this.conversionType.isAssignableFrom(values.get(0).getClass())) {
                 LOGGER.error("Attempted to assign attribute {} to list of type {} which is incompatible with {}.",
@@ -86,10 +84,10 @@ public class PluginElementVisitor extends AbstractPluginVisitor<PluginElement, O
         }
         final Node namedNode = findNamedNode(name, node.getChildren());
         if (namedNode == null) {
-            log.append(name).append("=null");
+            debugLog.append(name).append("=null");
             return null;
         }
-        log.append(namedNode.getName()).append('(').append(namedNode.toString()).append(')');
+        debugLog.append(namedNode.getName()).append('(').append(namedNode.toString()).append(')');
         node.getChildren().remove(namedNode);
         return namedNode.getObject();
     }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginInjectionBuilder.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginInjectionBuilder.java
new file mode 100644
index 0000000..6dadc77
--- /dev/null
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginInjectionBuilder.java
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+
+package org.apache.logging.log4j.plugins.inject;
+
+import org.apache.logging.log4j.plugins.Node;
+import org.apache.logging.log4j.plugins.util.Builder;
+import org.apache.logging.log4j.status.StatusLogger;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
+import java.util.Optional;
+import java.util.function.Function;
+
+/**
+ * Builder strategy for parsing and injecting a configuration node. Implementations should contain a default constructor
+ * and must provide a {@link #build()} implementation. This provides type conversion based on the injection point via
+ * {@link org.apache.logging.log4j.plugins.convert.TypeConverters}.
+ *
+ * @param <Ann> the Annotation type.
+ * @param <Cfg> the Configuration type.
+ */
+public interface PluginInjectionBuilder<Ann extends Annotation, Cfg> extends Builder<Object> {
+
+    /**
+     * Creates a PluginInjectionBuilder instance for the given annotation class using metadata provided by the annotation's
+     * {@link InjectionStrategy} annotation. This instance must be further populated with
+     * data before being {@linkplain #build() built} to be useful.
+     *
+     * @param injectorType the Plugin annotation class to find a PluginInjectionBuilder for.
+     * @return a PluginInjectionBuilder instance if one could be created or empty.
+     */
+    @SuppressWarnings("unchecked")
+    static <Ann extends Annotation, Cfg> Optional<PluginInjectionBuilder<Ann, Cfg>> findBuilderForInjectionStrategy(final Class<Ann> injectorType) {
+        return Optional.ofNullable(injectorType.getAnnotation(InjectionStrategy.class))
+                .flatMap(type -> {
+                    try {
+                        return Optional.of((PluginInjectionBuilder<Ann, Cfg>) type.value().newInstance());
+                    } catch (final Exception e) {
+                        StatusLogger.getLogger().error("Error loading PluginBuilder [{}] for annotation [{}].", type.value(), injectorType, e);
+                        return Optional.empty();
+                    }
+                });
+    }
+
+    /**
+     * Sets the Annotation to be used for this. If the given Annotation is not compatible with this class's type, then
+     * it is ignored.
+     *
+     * @param annotation the Annotation instance.
+     * @return {@code this}.
+     * @throws NullPointerException if the argument is {@code null}.
+     */
+    PluginInjectionBuilder<Ann, Cfg> withAnnotation(Annotation annotation);
+
+    /**
+     * Sets the list of aliases to use for this injection. No aliases are required, however.
+     *
+     * @param aliases the list of aliases to use.
+     * @return {@code this}.
+     */
+    PluginInjectionBuilder<Ann, Cfg> withAliases(String... aliases);
+
+    /**
+     * Sets the class to convert the plugin value to for injection. This should correspond with a class obtained from
+     * a factory method or builder class field. Not all PluginInjectionBuilder implementations may need this value.
+     *
+     * @param conversionType the type to convert the plugin string to (if applicable).
+     * @return {@code this}.
+     * @throws NullPointerException if the argument is {@code null}.
+     */
+    PluginInjectionBuilder<Ann, Cfg> withConversionType(Class<?> conversionType);
+
+    /**
+     * Sets the Member that this builder is being used for injection upon. For instance, this could be the Field
+     * that is being used for injecting a value, or it could be the factory method being used to inject parameters
+     * into.
+     *
+     * @param member the member this builder is parsing a value for.
+     * @return {@code this}.
+     */
+    PluginInjectionBuilder<Ann, Cfg> withMember(Member member);
+
+    PluginInjectionBuilder<Ann, Cfg> withStringSubstitutionStrategy(Function<String, String> stringSubstitutionStrategy);
+
+    PluginInjectionBuilder<Ann, Cfg> withDebugLog(StringBuilder debugLog);
+
+    PluginInjectionBuilder<Ann, Cfg> withConfiguration(Cfg configuration);
+
+    PluginInjectionBuilder<Ann, Cfg> withConfigurationNode(Node node);
+}
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginNodeVisitor.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginNodeBuilder.java
similarity index 68%
rename from log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginNodeVisitor.java
rename to log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginNodeBuilder.java
index 9438b39..3cf2189 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginNodeVisitor.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginNodeBuilder.java
@@ -15,26 +15,22 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.plugins.visitors;
+package org.apache.logging.log4j.plugins.inject;
 
-import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.PluginNode;
 
-import java.util.function.Function;
-
 /**
- * PluginVisitor implementation for {@link PluginNode}.
+ * PluginInjectionBuilder implementation for {@link PluginNode}.
  */
-public class PluginNodeVisitor extends AbstractPluginVisitor<PluginNode, Object> {
-    public PluginNodeVisitor() {
+public class PluginNodeBuilder extends AbstractPluginInjectionBuilder<PluginNode, Object> {
+    public PluginNodeBuilder() {
         super(PluginNode.class);
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         if (this.conversionType.isInstance(node)) {
-            log.append("Node=").append(node.getName());
+            debugLog.append("Node=").append(node.getName());
             return node;
         }
         LOGGER.warn("Variable annotated with @PluginNode is not compatible with the type {}.", node.getClass());
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginValueVisitor.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginValueBuilder.java
similarity index 75%
rename from log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginValueVisitor.java
rename to log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginValueBuilder.java
index 2f68f04..a9e5f0e 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginValueVisitor.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/PluginValueBuilder.java
@@ -15,26 +15,22 @@
  * limitations under the license.
  */
 
-package org.apache.logging.log4j.plugins.visitors;
+package org.apache.logging.log4j.plugins.inject;
 
-import org.apache.logging.log4j.plugins.Node;
 import org.apache.logging.log4j.plugins.PluginValue;
 import org.apache.logging.log4j.util.StringBuilders;
 import org.apache.logging.log4j.util.Strings;
 
-import java.util.function.Function;
-
 /**
- * PluginVisitor implementation for {@link PluginValue}.
+ * PluginInjectionBuilder implementation for {@link PluginValue}.
  */
-public class PluginValueVisitor extends AbstractPluginVisitor<PluginValue, Object> {
-    public PluginValueVisitor() {
+public class PluginValueBuilder extends AbstractPluginInjectionBuilder<PluginValue, Object> {
+    public PluginValueBuilder() {
         super(PluginValue.class);
     }
 
     @Override
-    public Object visit(final Object unused, final Node node, final Function<String, String> substitutor,
-                        final StringBuilder log) {
+    public Object build() {
         final String name = this.annotation.value();
         final String elementValue = node.getValue();
         final String attributeValue = node.getAttributes().get("value");
@@ -49,8 +45,8 @@ public class PluginValueVisitor extends AbstractPluginVisitor<PluginValue, Objec
         } else {
             rawValue = removeAttributeValue(node.getAttributes(), "value");
         }
-        final String value = substitutor.apply(rawValue);
-        StringBuilders.appendKeyDqValue(log, name, value);
+        final String value = stringSubstitutionStrategy.apply(rawValue);
+        StringBuilders.appendKeyDqValue(debugLog, name, value);
         return value;
     }
 }
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/package-info.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/package-info.java
similarity index 67%
rename from log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/package-info.java
rename to log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/package-info.java
index 0855b16..a359ce0 100644
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/package-info.java
+++ b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/inject/package-info.java
@@ -16,9 +16,8 @@
  */
 
 /**
- * Visitor classes for extracting values from a Configuration or Node corresponding to a plugin annotation.
- * Visitor implementations must implement {@link org.apache.logging.log4j.plugins.visitors.PluginVisitor},
- * and the corresponding annotation must be annotated with
- * {@link org.apache.logging.log4j.plugins.PluginVisitorStrategy}.
+ * Injection builder classes for parsing data from a {@code Configuration} or {@link org.apache.logging.log4j.plugins.Node}
+ * corresponding to an {@link org.apache.logging.log4j.plugins.inject.InjectionStrategy}-annotated annotation.
+ * Injection strategies must implement {@link org.apache.logging.log4j.plugins.inject.PluginInjectionBuilder}.
  */
-package org.apache.logging.log4j.plugins.visitors;
+package org.apache.logging.log4j.plugins.inject;
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginVisitor.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginVisitor.java
deleted file mode 100644
index fb7aca4..0000000
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginVisitor.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-
-package org.apache.logging.log4j.plugins.visitors;
-
-import org.apache.logging.log4j.plugins.Node;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Member;
-import java.util.function.Function;
-
-/**
- * Visitor strategy for parsing data from a {@link Node}, doing any relevant type conversion, and returning a
- * parsed value for that variable. Implementations must be constructable using the default constructor.
- *
- * @param <A> the Annotation type.
- */
-public interface PluginVisitor<A extends Annotation, T> {
-
-    /**
-     * Sets the Annotation to be used for this. If the given Annotation is not compatible with this class's type, then
-     * it is ignored.
-     *
-     * @param annotation the Annotation instance.
-     * @return {@code this}.
-     * @throws NullPointerException if the argument is {@code null}.
-     */
-    PluginVisitor<A, T> setAnnotation(Annotation annotation);
-
-    /**
-     * Sets the list of aliases to use for this visit. No aliases are required, however.
-     *
-     * @param aliases the list of aliases to use.
-     * @return {@code this}.
-     */
-    PluginVisitor<A, T> setAliases(String... aliases);
-
-    /**
-     * Sets the class to convert the plugin value to on this visit. This should correspond with a class obtained from
-     * a factory method or builder class field. Not all PluginVisitor implementations may need this value.
-     *
-     * @param conversionType the type to convert the plugin string to (if applicable).
-     * @return {@code this}.
-     * @throws NullPointerException if the argument is {@code null}.
-     */
-    PluginVisitor<A, T> setConversionType(Class<?> conversionType);
-
-    /**
-     * Sets the Member that this visitor is being used for injection upon. For instance, this could be the Field
-     * that is being used for injecting a value, or it could be the factory method being used to inject parameters
-     * into.
-     *
-     * @param member the member this visitor is parsing a value for.
-     * @return {@code this}.
-     */
-    PluginVisitor<A, T> setMember(Member member);
-
-    /**
-     * Visits a Node to obtain a value for constructing a Plugin object.
-     *
-     * @param configuration the current Configuration.
-     * @param node          the current Node corresponding to the Plugin object being created.
-     * @param substitutor   the function to perform String substitutions.
-     * @param log           th e StringBuilder being used to build a debug message.
-     * @return the converted value to be used for Plugin creation.
-     */
-    Object visit(T configuration, Node node, Function<String, String> substitutor, StringBuilder log);
-}
diff --git a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginVisitors.java b/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginVisitors.java
deleted file mode 100644
index 695d387..0000000
--- a/log4j-plugins/src/main/java/org/apache/logging/log4j/plugins/visitors/PluginVisitors.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-
-package org.apache.logging.log4j.plugins.visitors;
-
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.plugins.PluginVisitorStrategy;
-import org.apache.logging.log4j.status.StatusLogger;
-
-import java.lang.annotation.Annotation;
-
-/**
- * Utility class to locate an appropriate {@link PluginVisitor} implementation for an annotation.
- */
-public final class PluginVisitors {
-
-    private static final Logger LOGGER = StatusLogger.getLogger();
-
-    private PluginVisitors() {
-    }
-
-    /**
-     * Creates a PluginVisitor instance for the given annotation class using metadata provided by the annotation's
-     * {@link PluginVisitorStrategy} annotation. This instance must be further populated with
-     * data to be useful. Such data is passed through both the setters and the visit method.
-     *
-     * @param annotation the Plugin annotation class to find a PluginVisitor for.
-     * @return a PluginVisitor instance if one could be created, or {@code null} otherwise.
-     */
-    public static <T> PluginVisitor<? extends Annotation, T> findVisitor(final Class<? extends Annotation> annotation) {
-        final PluginVisitorStrategy strategy = annotation.getAnnotation(PluginVisitorStrategy.class);
-        if (strategy == null) {
-            return null;
-        }
-        try {
-            return (PluginVisitor<? extends Annotation, T>) strategy.value().newInstance();
-        } catch (final Exception e) {
-            LOGGER.error("Error loading PluginVisitor [{}] for annotation [{}].", strategy.value(), annotation, e);
-            return null;
-        }
-    }
-}
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 2b19f00..7b50e41 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -30,7 +30,10 @@
          - "update" - Change
          - "remove" - Removed
     -->
-    <release version="3.0.0" date="2018-xx-xx" description="GA Release 3.0.0">
+    <release version="3.0.0" date="2019-xx-xx" description="GA Release 3.0.0">
+      <action issue="LOG4J2-2683" dev="mattsicker" type="update">
+        Rename PluginVisitor and related classes to PluginInjectionBuilder.
+      </action>
       <action issue="LOG4J2-2523" dev="rgoers" type="update" due-to="Romain Manni-Bucau">
         Allow web lookup to access more information.
       </action>
@@ -39,7 +42,7 @@
         file compatible with java.util.ServiceLoader instead of a binary file.
       </action>
       <action issue="LOG4J2-2025" dev="rgoers" type="add" due-to="Thies Wellpott">
-        Implement JUL Bridge Handler..
+        Implement JUL Bridge Handler.
       </action>
       <action issue="LOG4J2-2171" dev="rmannibucau" type="add">
         Allow to force LOG4J2 to use TCCL only.