/** * Get a resource as a URL using the current class path * * @param resource * - the resource to locate * * @return the resource or null */ public URL getResourceAsURL(String resource) { return getResourceAsURL(resource, getClassLoaders(null)); }
/** * Get a resource from the classpath, starting with a specific class loader * * @param resource * - the resource to find * @param classLoader * - the first classloader to try * * @return the stream or null */ public URL getResourceAsURL(String resource, ClassLoader classLoader) { return getResourceAsURL(resource, getClassLoaders(classLoader)); }
/** * Get a resource as a URL using the current class path * * @param resource * - the resource to locate * @param classLoader * - the class loaders to examine * * @return the resource or null */ URL getResourceAsURL(String resource, ClassLoader[] classLoader) {
URL url; // 遍历classLoader数组 for (ClassLoader cl : classLoader) {
if (null != cl) { // 获得不带 / 的 URL // look for the resource as passed in... url = cl.getResource(resource); // 获得带 / 的 URL // ...but some class loaders want this leading "/", so we'll add it // and try again if we didn't find the resource if (null == url) { url = cl.getResource("/" + resource); }
// "It's always in the last place I look for it!" // ... because only an idiot would keep looking for it after finding it, so stop looking already. if (null != url) { return url; }
/** * Get a resource from the classpath * * @param resource * - the resource to find * * @return the stream or null */ public InputStream getResourceAsStream(String resource) { return getResourceAsStream(resource, getClassLoaders(null)); }
/** * Get a resource from the classpath, starting with a specific class loader * * @param resource * - the resource to find * @param classLoader * - the first class loader to try * * @return the stream or null */ public InputStream getResourceAsStream(String resource, ClassLoader classLoader) { return getResourceAsStream(resource, getClassLoaders(classLoader)); }
/** * Try to get a resource from a group of classloaders * * @param resource * - the resource to get * @param classLoader * - the classloaders to examine * * @return the resource or null */ InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) { // 遍历 classLoader 数组 for (ClassLoader cl : classLoader) { if (null != cl) {
// try to find the resource as passed // 获得不带 / 的InputStream InputStreamreturnValue= cl.getResourceAsStream(resource);
// now, some class loaders want this leading "/", so we'll add it and try again if we didn't find the resource // 获得带 / 的InputStream if (null == returnValue) { returnValue = cl.getResourceAsStream("/" + resource); } // 返回结果 if (null != returnValue) { return returnValue; } } } returnnull; }
/** * Find a class on the classpath (or die trying) * * @param name * - the class to look for * * @return - the class * * @throws ClassNotFoundException * Duh. */ public Class<?> classForName(String name) throws ClassNotFoundException { return classForName(name, getClassLoaders(null)); }
/** * Find a class on the classpath, starting with a specific classloader (or die trying) * * @param name * - the class to look for * @param classLoader * - the first classloader to try * * @return - the class * * @throws ClassNotFoundException * Duh. */ public Class<?> classForName(String name, ClassLoader classLoader) throws ClassNotFoundException { return classForName(name, getClassLoaders(classLoader)); }
/** * Attempt to load a class from a group of classloaders * * @param name * - the class to load * @param classLoader * - the group of classloaders to examine * * @return the class * * @throws ClassNotFoundException * - Remember the wisdom of Judge Smails: Well, the world needs ditch diggers, too. */ Class<?> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {
// 遍历 classLoader 数组 for (ClassLoader cl : classLoader) {
/** * Returns the URL of the resource on the classpath * * @param resource * The resource to find * * @return The resource * * @throws java.io.IOException * If the resource cannot be found or read */ publicstatic URL getResourceURL(String resource)throws IOException { // issue #625 return getResourceURL(null, resource); }
/** * Returns the URL of the resource on the classpath * * @param loader * The classloader used to fetch the resource * @param resource * The resource to find * * @return The resource * * @throws java.io.IOException * If the resource cannot be found or read */ publicstatic URL getResourceURL(ClassLoader loader, String resource)throws IOException { URLurl= classLoaderWrapper.getResourceAsURL(resource, loader); if (url == null) { thrownewIOException("Could not find resource " + resource); } return url; }
/** * Returns a resource on the classpath as a Stream object * * @param resource * The resource to find * * @return The resource * * @throws java.io.IOException * If the resource cannot be found or read */ publicstatic InputStream getResourceAsStream(String resource)throws IOException { return getResourceAsStream(null, resource); }
/** * Returns a resource on the classpath as a Stream object * * @param loader * The classloader used to fetch the resource * @param resource * The resource to find * * @return The resource * * @throws java.io.IOException * If the resource cannot be found or read */ publicstatic InputStream getResourceAsStream(ClassLoader loader, String resource)throws IOException { InputStreamin= classLoaderWrapper.getResourceAsStream(resource, loader); if (in == null) { thrownewIOException("Could not find resource " + resource); } return in; }
…. 省略其它代码 了解classLoaderWrapper即可
2.3 getUrl
获得指定URL的Reader / Properties
2.3.1 getUrlAsStream(String urlString)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * Gets a URL as an input stream * * @param urlString * - the URL to get * * @return An input stream with the data from the URL * * @throws java.io.IOException * If the resource cannot be found or read */ publicstatic InputStream getUrlAsStream(String urlString)throws IOException { URLurl=newURL(urlString); URLConnectionconn= url.openConnection(); return conn.getInputStream(); }
/** * Gets a URL as a Reader * * @param urlString * - the URL to get * * @return A Reader with the data from the URL * * @throws java.io.IOException * If the resource cannot be found or read */ publicstatic Reader getUrlAsReader(String urlString)throws IOException { Reader reader; if (charset == null) { reader = newInputStreamReader(getUrlAsStream(urlString)); } else { reader = newInputStreamReader(getUrlAsStream(urlString), charset); } return reader; }
2.3.3 getUrlAsProperties(String urlString)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/** * Gets a URL as a Properties object * * @param urlString * - the URL to get * * @return A Properties object with the data from the URL * * @throws java.io.IOException * If the resource cannot be found or read */ publicstatic Properties getUrlAsProperties(String urlString)throws IOException { Propertiesprops=newProperties(); try (InputStreamin= getUrlAsStream(urlString)) { props.load(in); } return props; }
2.3.4 classForName
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/** * Loads a class * * @param className * - the class to fetch * * @return The loaded class * * @throws ClassNotFoundException * If the class cannot be found (duh!) */ publicstatic Class<?> classForName(String className) throws ClassNotFoundException { return classLoaderWrapper.classForName(className); }
/** * A simple interface that specifies how to test classes to determine if they are to be included in the results * produced by the ResolverUtil. */ publicinterfaceTest {
/** * Will be called repeatedly with candidate classes. Must return True if a class is to be included in the results, * false otherwise. * * @param type * the type * * @return true, if successful */ booleanmatches(Class<?> type); }
/** * A Test that checks to see if each class is assignable to the provided class. Note that this test will match the * parent type itself if it is presented for matching. */ publicstaticclassIsAimplementsTest {
/** * Constructs an IsA test using the supplied Class as the parent class/interface. * * @param parentType * the parent type */ publicIsA(Class<?> parentType) { this.parent = parentType; }
/** Returns true if type is assignable to the parent type supplied in the constructor. */ @Override publicbooleanmatches(Class<?> type) { return type != null && parent.isAssignableFrom(type); }
@Override public String toString() { return"is assignable to " + parent.getSimpleName(); } }
/** * A Test that checks to see if each class is annotated with a specific annotation. If it is, then the test returns * true, otherwise false. */ publicstaticclassAnnotatedWithimplementsTest {
/** The annotation. */ privatefinal Class<? extendsAnnotation> annotation;
/** * Constructs an AnnotatedWith test for the specified annotation type. * * @param annotation * the annotation */ publicAnnotatedWith(Class<? extends Annotation> annotation) { this.annotation = annotation; }
/** Returns true if the type is annotated with the class provided to the constructor. */ @Override publicbooleanmatches(Class<?> type) { return type != null && type.isAnnotationPresent(annotation); }
@Override public String toString() { return"annotated with @" + annotation.getSimpleName(); } }
/** The set of matches being accumulated. */ // 符合条件的类的集合 private Set<Class<? extendsT>> matches = newHashSet<>();
/** * The ClassLoader to use when looking for classes. If null then the ClassLoader returned by * Thread.currentThread().getContextClassLoader() will be used. */ private ClassLoader classloader;
/** * Provides access to the classes discovered so far. If no calls have been made to any of the {@code find()} methods, * this set will be empty. * * @return the set of classes that have been discovered. */ public Set<Class<? extendsT>> getClasses() { return matches; }
/** * Returns the classloader that will be used for scanning for classes. If no explicit ClassLoader has been set by the * calling, the context class loader will be used. * * @return the ClassLoader that will be used to scan for classes */ public ClassLoader getClassLoader() { return classloader == null ? Thread.currentThread().getContextClassLoader() : classloader; }
/** * Sets an explicit ClassLoader that should be used when scanning for classes. If none is set then the context * classloader will be used. * * @param classloader * a ClassLoader to use when scanning for classes */ publicvoidsetClassLoader(ClassLoader classloader) { this.classloader = classloader; }