001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans.factory.serviceloader; 018 019import java.util.ServiceLoader; 020 021import org.springframework.beans.factory.BeanClassLoaderAware; 022import org.springframework.beans.factory.config.AbstractFactoryBean; 023import org.springframework.lang.Nullable; 024import org.springframework.util.Assert; 025import org.springframework.util.ClassUtils; 026 027/** 028 * Abstract base class for FactoryBeans operating on the 029 * JDK 1.6 {@link java.util.ServiceLoader} facility. 030 * 031 * @author Juergen Hoeller 032 * @since 2.5 033 * @see java.util.ServiceLoader 034 */ 035public abstract class AbstractServiceLoaderBasedFactoryBean extends AbstractFactoryBean<Object> 036 implements BeanClassLoaderAware { 037 038 @Nullable 039 private Class<?> serviceType; 040 041 @Nullable 042 private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); 043 044 045 /** 046 * Specify the desired service type (typically the service's public API). 047 */ 048 public void setServiceType(@Nullable Class<?> serviceType) { 049 this.serviceType = serviceType; 050 } 051 052 /** 053 * Return the desired service type. 054 */ 055 @Nullable 056 public Class<?> getServiceType() { 057 return this.serviceType; 058 } 059 060 @Override 061 public void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) { 062 this.beanClassLoader = beanClassLoader; 063 } 064 065 066 /** 067 * Delegates to {@link #getObjectToExpose(java.util.ServiceLoader)}. 068 * @return the object to expose 069 */ 070 @Override 071 protected Object createInstance() { 072 Assert.notNull(getServiceType(), "Property 'serviceType' is required"); 073 return getObjectToExpose(ServiceLoader.load(getServiceType(), this.beanClassLoader)); 074 } 075 076 /** 077 * Determine the actual object to expose for the given ServiceLoader. 078 * <p>Left to concrete subclasses. 079 * @param serviceLoader the ServiceLoader for the configured service class 080 * @return the object to expose 081 */ 082 protected abstract Object getObjectToExpose(ServiceLoader<?> serviceLoader); 083 084}