I've been doing some experiments with the plugin system for 3.x
lately, and I've recently pushed some changes toward that end. One of
the insights I gained from it was that some of our plugin annotations
were redundant (result: @PluginBuilderFactory merged into
@PluginFactory; @PluginBuilderAttribute deprecated for merging into
@PluginAttribute). After making those changes, I realized that @Plugin
and @PluginFactory didn't necessarily need to be separate annotations,
though I hadn't written any code to try that out yet. However, I did
realize over time that I was essentially reinventing a mini dependency
injection framework (hence the historical references to Spring and
Java EE concepts in the code or comments). In that regard, I
identified that all the current plugin annotations can be categorized
as follows:

* @Plugin - essentially identifies an injectable class and its name.
* @PluginAliases - alternative names for annotated elements
* @PluginFactory - marks the injection point for a plugin
* @PluginElement, @PluginNode, @PluginConfiguration - all type-based
dependency injection corresponding to other plugins (seems to apply
regardless of the element name as well)
* @PluginAttribute, @PluginValue, etc. - all name-based configuration injection

What I'd like to propose is a vast simplification of this system to
reuse the javax.inject API [1] since we've already split out
log4j-plugins into its own dependency. As you can see, it's a fairly
small package, though we could potentially reuse the API without the
package names, too. A general conversion of API usage would work like
such:

* @Plugin name can be replaced by @Named annotation
* Aliases can still be specified by a separate annotation
* @PluginElement can be a specific @Scope annotation and generally
rely on @Inject
* @PluginFactory can be replaced by @Inject
* Builder<T> can be replaced by Provider<T>
* @PluginAttribute can be replaced by @Named @Inject of simple types
as well as maybe @Qualifier in general

I can work on a PoC for this, though I wanted to see if this idea was
acceptable here. I don't want to introduce a full blown dependency
injection framework like Guice/Spring/CDI/etc. since all we need is a
way to bind configurations to a specific object graph, though the ad
hoc nature of plugins in the past has made some things harder to keep
a stable API for, and I think this could help improve that situation.

By going with the standardized annotations, we might also be able to
take advantage of other tooling for generating static representations
of a configuration for AOT compilation in microservices or other neat
things.

[1]: https://docs.oracle.com/javaee/7/api/javax/inject/package-summary.html

-- 
Matt Sicker <boa...@gmail.com>

Reply via email to