servicefinder.java
来自「resetful样式的ws样例,一种面向资源的webservices服务」· Java 代码 · 共 689 行 · 第 1/3 页
JAVA
689 行
/* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common Development * and Distribution License("CDDL") (collectively, the "License"). You * may not use this file except in compliance with the License. You can obtain * a copy of the License at https://jersey.dev.java.net/CDDL+GPL.html * or jersey/legal/LICENSE.txt. See the License for the specific * language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each * file and include the License file at jersey/legal/LICENSE.txt. * Sun designates this particular file as subject to the "Classpath" exception * as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own * identifying information: "Portions Copyrighted [year] * [name of copyright owner]" * * Contributor(s): * * If you wish your version of this file to be governed by only the CDDL or * only the GPL Version 2, indicate your decision by adding "[Contributor] * elects to include this software in this distribution under the [CDDL or GPL * Version 2] license." If you don't indicate a single choice of license, a * recipient has the option to distribute your version of this file under * either the CDDL, the GPL Version 2 or to extend the choice of license to * its licensees as provided above. However, if you add GPL Version 2 code * and therefore, elected the GPL Version 2 license, then the option applies * only if the new code is made subject to such option by the copyright * holder. */package com.sun.jersey.spi.service;import com.sun.jersey.spi.SpiMessages;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.lang.reflect.Array;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;import java.net.URL;import java.net.URLConnection;import java.util.ArrayList;import java.util.Enumeration;import java.util.Iterator;import java.util.List;import java.util.NoSuchElementException;import java.util.Set;import java.util.TreeSet;import java.util.logging.Level;import java.util.logging.Logger;/** * A simple service-provider lookup mechanism. A <i>service</i> is a * well-known set of interfaces and (usually abstract) classes. A <i>service * provider</i> is a specific implementation of a service. The classes in a * provider typically implement the interfaces and subclass the classes defined * in the service itself. Service providers may be installed in an * implementation of the Java platform in the form of extensions, that is, jar * files placed into any of the usual extension directories. Providers may * also be made available by adding them to the applet or application class * path or by some other platform-specific means. * <p/> * <p> In this lookup mechanism a service is represented by an interface or an * abstract class. (A concrete class may be used, but this is not * recommended.) A provider of a given service contains one or more concrete * classes that extend this <i>service class</i> with data and code specific to * the provider. This <i>provider class</i> will typically not be the entire * provider itself but rather a proxy that contains enough information to * decide whether the provider is able to satisfy a particular request together * with code that can create the actual provider on demand. The details of * provider classes tend to be highly service-specific; no single class or * interface could possibly unify them, so no such class has been defined. The * only requirement enforced here is that provider classes must have a * zero-argument constructor so that they may be instantiated during lookup. * <p/> * <p> A service provider identifies itself by placing a provider-configuration * file in the resource directory <tt>META-INF/services</tt>. The file's name * should consist of the fully-qualified name of the abstract service class. * The file should contain a list of fully-qualified concrete provider-class * names, one per line. Space and tab characters surrounding each name, as * well as blank lines, are ignored. The comment character is <tt>'#'</tt> * (<tt>0x23</tt>); on each line all characters following the first comment * character are ignored. The file must be encoded in UTF-8. * <p/> * <p> If a particular concrete provider class is named in more than one * configuration file, or is named in the same configuration file more than * once, then the duplicates will be ignored. The configuration file naming a * particular provider need not be in the same jar file or other distribution * unit as the provider itself. The provider must be accessible from the same * class loader that was initially queried to locate the configuration file; * note that this is not necessarily the class loader that found the file. * <p/> * <p> <b>Example:</b> Suppose we have a service class named * <tt>java.io.spi.CharCodec</tt>. It has two abstract methods: * <p/> * <pre> * public abstract CharEncoder getEncoder(String encodingName); * public abstract CharDecoder getDecoder(String encodingName); * </pre> * <p/> * Each method returns an appropriate object or <tt>null</tt> if it cannot * translate the given encoding. Typical <tt>CharCodec</tt> providers will * support more than one encoding. * <p/> * <p> If <tt>sun.io.StandardCodec</tt> is a provider of the <tt>CharCodec</tt> * service then its jar file would contain the file * <tt>META-INF/services/java.io.spi.CharCodec</tt>. This file would contain * the single line: * <p/> * <pre> * sun.io.StandardCodec # Standard codecs for the platform * </pre> * <p/> * To locate an codec for a given encoding name, the internal I/O code would * do something like this: * <p/> * <pre> * CharEncoder getEncoder(String encodingName) { * for( CharCodec cc : ServiceFinder.find(CharCodec.class) ) { * CharEncoder ce = cc.getEncoder(encodingName); * if (ce != null) * return ce; * } * return null; * } * </pre> * <p/> * The provider-lookup mechanism always executes in the security context of the * caller. Trusted system code should typically invoke the methods in this * class from within a privileged security context. * * @author Mark Reinhold * @version 1.11, 03/12/19 * @since 1.3 */public final class ServiceFinder<T> implements Iterable<T> { private static final Logger LOGGER = Logger.getLogger(ServiceFinder.class.getName()); private static final String PREFIX = "META-INF/services/"; private static final ComponentProvider DEFAULT_COMPONENT_PROVIDER = new ComponentProvider() { public <T> T getInstance(Scope scope, Class<T> c) throws InstantiationException, IllegalAccessException { return c.newInstance(); } public <T> T getInstance(Scope scope, Constructor<T> contructor, Object[] parameters) throws InstantiationException, IllegalArgumentException, IllegalAccessException, InvocationTargetException { throw new UnsupportedOperationException(""); } public <T> T getInstance(ComponentContext cc, Scope scope, Class<T> c) throws InstantiationException, IllegalAccessException { return getInstance(scope, c); } public <T> T getInjectableInstance(T instance) { return instance; } public void inject(Object instance) { throw new UnsupportedOperationException(""); } }; private final Class<T> serviceClass; private final ClassLoader classLoader; private final boolean ignoreOnClassNotFound; private final ComponentProvider componentProvider; /** * Locates and incrementally instantiates the available providers of a * given service using the given class loader. * <p/> * <p> This method transforms the name of the given service class into a * provider-configuration filename as described above and then uses the * <tt>getResources</tt> method of the given class loader to find all * available files with that name. These files are then read and parsed to * produce a list of provider-class names. The iterator that is returned * uses the given class loader to lookup and then instantiate each element * of the list. * <p/> * <p> Because it is possible for extensions to be installed into a running * Java virtual machine, this method may return different results each time * it is invoked. <p> * @param service The service's abstract service class * @param loader The class loader to be used to load provider-configuration files * and instantiate provider classes, or <tt>null</tt> if the system * class loader (or, failing that the bootstrap class loader) is to * be used * @throws ServiceConfigurationError If a provider-configuration file violates the specified format * or names a provider class that cannot be found and instantiated * @see #find(Class) * @return the service finder */ public static <T> ServiceFinder<T> find(Class<T> service, ClassLoader loader) throws ServiceConfigurationError { return find(service, loader, false, DEFAULT_COMPONENT_PROVIDER); } /** * Locates and incrementally instantiates the available providers of a * given service using the given class loader. * <p/> * <p> This method transforms the name of the given service class into a * provider-configuration filename as described above and then uses the * <tt>getResources</tt> method of the given class loader to find all * available files with that name. These files are then read and parsed to * produce a list of provider-class names. The iterator that is returned * uses the given class loader to lookup and then instantiate each element * of the list. * <p/> * <p> Because it is possible for extensions to be installed into a running * Java virtual machine, this method may return different results each time * it is invoked. <p> * @param service The service's abstract service class
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?