commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dblev...@apache.org
Subject svn commit: r1346686 - /commons/sandbox/classscan/branches/commons-finder/ResourceFinder.mdtext
Date Wed, 06 Jun 2012 00:42:34 GMT
Author: dblevins
Date: Wed Jun  6 00:42:33 2012
New Revision: 1346686

URL: http://svn.apache.org/viewvc?rev=1346686&view=rev
Log:
Some minimal markdown doc on ResourceFinder

Added:
    commons/sandbox/classscan/branches/commons-finder/ResourceFinder.mdtext

Added: commons/sandbox/classscan/branches/commons-finder/ResourceFinder.mdtext
URL: http://svn.apache.org/viewvc/commons/sandbox/classscan/branches/commons-finder/ResourceFinder.mdtext?rev=1346686&view=auto
==============================================================================
--- commons/sandbox/classscan/branches/commons-finder/ResourceFinder.mdtext (added)
+++ commons/sandbox/classscan/branches/commons-finder/ResourceFinder.mdtext Wed Jun  6 00:42:33
2012
@@ -0,0 +1,105 @@
+Taken from a StackOverflow answer on how to use ResourceFinder to replace ServiceLoader.
+
+`ResourceFinder` can do more than what is described later in this doc, fore example:
+
+    final URL someJar = ..//
+    final ResourceFinder finder = new ResourceFinder(someJar);
+    final Map<String, URL> deploymentDescriptors = finder.getResourcesMap("META-INF");
+
+
+# ResourceFinder
+
+* [ResourceFinder][1] is a self-contained java file capable of replacing ServiceLoader usage
as well as `classLoader.getResource()` calls.
+
+Before our attention spans get too short, here's how it can replace a `ServiceLoader`
+
+    ResourceFinder finder = new ResourceFinder("META-INF/services/");
+    List<Class<? extends Plugin>> impls = finder.findAllImplementations(Plugin.class);
+
+This will find all of the `META-INF/services/org.acme.Plugin` implementations in your classpath.
+
+Note it does not actually instantiate all the instances.  Pick the one(s) you want and you're
one `newInstance()` call away from having an instance.
+
+Why is this nice?
+
+  - How hard is it to call `newInstance()` with proper exception handling?  Not hard.
+  - Having the freedom to instantiate only the ones you want is nice.
+  - Now you can support constructor args!
+
+Searching for xml files also becomes easy
+
+    ResourceFinder finder = new ResourceFinder();
+    List<Class<? extends Plugin>> impls = finder.findAllImplementations(Plugin.class);
+
+## Narrowing search scope
+
+If you want to just check specific URLs you can do so easily:
+
+    URL url = new File("some.jar").toURI().toURL();
+    ResourceFinder finder = new ResourceFinder("META-INF/services/", url);
+
+Here, only the 'some.jar' will be searched on any usage of this ResourceFinder instance.
+
+There's also a convenience class called `UrlSet` which can make selecting URLs from the classpath
very easy.
+
+    ClassLoader webAppClassLoader = Thread.currentThread().getContextClassLoader();
+    UrlSet urlSet = new UrlSet(webAppClassLoader);
+    urlSet = urlSet.exclude(webAppClassLoader.getParent());
+    urlSet = urlSet.matching(".*acme-.*.jar");
+
+    List<URL> urls = urlSet.getUrls();
+
+## Alternate "service" styles
+
+Say you wanted to apply the `ServiceLoader` type concept to redesign URL handling and find/load
the `java.net.URLStreamHandler` for a specific protocol.
+
+Here's how you might layout the services in your classpath:
+
+  - `META-INF/java.net.URLStreamHandler/foo`
+  - `META-INF/java.net.URLStreamHandler/bar`
+  - `META-INF/java.net.URLStreamHandler/baz`
+
+Where `foo` is a plain text file that contains the name of the service implementation just
as before.  Now say someone creates a `foo://...` URL.  We can find the implementation for
that quickly, via:
+
+    ResourceFinder finder = new ResourceFinder("META-INF/");
+    Map<String, Class<? extends URLStreamHandler>> handlers = finder.mapAllImplementations(URLStreamHandler.class);
+    Class<? extends URLStreamHandler> fooHandler = handlers.get("foo");
+
+## Alternate "service" styles 2
+
+Say you wanted to put some configuration information in your service file, so it contains
more than just a classname.  Here's an alternate style that resolves services to properties
files.  By convention one key would be the class names and the other keys would be injectable
properties.
+
+So here `red` is a properties file
+
+  - `META-INF/org.acme.Plugin/red`
+  - `META-INF/org.acme.Plugin/blue`
+  - `META-INF/org.acme.Plugin/green`
+
+You can look things up similarly as before.
+
+    ResourceFinder finder = new ResourceFinder("META-INF/");
+
+    Map<String,Properties> plugins = finder.mapAllProperties(Plugin.class.getName());
+    Properties redDefinition = plugins.get("red");
+
+Here's how you could use those properties with `xbean-reflect`, another little library that
can give you framework-free IoC.  You just give it the class name and some name value pairs
and it will construct and inject.
+
+    ObjectRecipe recipe = new ObjectRecipe(redDefinition.remove("className").toString());
+    recipe.setAllProperties(redDefinition);
+
+    Plugin red = (Plugin) recipe.create();
+    red.start();
+
+Here's how that might look "spelled" out in long form:
+
+    ObjectRecipe recpie = new ObjectRecipe("com.example.plugins.RedPlugin");
+    recpie.setProperty("myDateField","2011-08-29");
+    recpie.setProperty("myIntField","100");
+    recpie.setProperty("myBooleanField","true");
+    recpie.setProperty("myUrlField","http://www.stackoverflow.com");
+    Plugin red = (Plugin) recpie.create();
+    red.start();
+
+
+The `xbean-reflect` library is a step beyond the built-in JavaBeans API, but a bit better
without requiring you to go all the way to a full-on IoC framework like Guice or Spring. 
It supports factory methods and constructor args and setter/field injection.
+



Mime
View raw message