package com.sooka; import com.sooka.jersey.provider.GsonProvider; import com.sooka.provider.AuthRequestFilter; import lombok.extern.slf4j.Slf4j; import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.server.ResourceConfig; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReader; import org.springframework.stereotype.Component; import org.springframework.util.ClassUtils; import java.io.IOException; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @Component @Slf4j public class Application extends ResourceConfig { private static final Logger LOGGER = Logger.getLogger(Application.class.getName()); public Application() { // 注册逻辑处理的包名 registerClasses(findAllClasses()); register(TestApiApplication.class); // 给Jersey注册MultiPart的支持库,用以上传文件 register(MultiPartFeature.class); // 注册我们的全局请求拦截器 register(AuthRequestFilter.class); // 注册Json解析器 // register(JacksonJsonProvider.class); // 替换解析器为Gson register(GsonProvider.class); // 注册日志打印输出 register(Logger.class); // 输出启动成功日志 LOGGER.log(Level.INFO, "Application setup succeed!"); } /** * 由于spring boot 打包为jar包,jersey packages 无法扫描jar对应的文件夹的文件,故自定义包扫描 * @return */ private Set> findAllClasses(){ // String scanPackages = "com.sooka.api.*"; String scanPackages = "com.sooka.**.*"; ClassLoader loader = this.getClass().getClassLoader(); Resource[] resources = new Resource[0]; try { resources = scan(loader, scanPackages); } catch (IOException e) { log.error("加载class异常",e); } return convert(loader, resources); } /** * 扫描 jar 包 * @param loader * @param packageName * @return * @throws IOException */ private Resource[] scan(ClassLoader loader, String packageName) throws IOException { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(loader); String pattern = "classpath*:" + ClassUtils.convertClassNameToResourcePath(packageName) + ".class"; return resolver.getResources(pattern); } /** * 加载 class * @param loader * @param resource * @return */ private Class loadClass(ClassLoader loader,Resource resource) { try { CachingMetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(loader); MetadataReader reader = metadataReaderFactory.getMetadataReader(resource); return ClassUtils.forName(reader.getClassMetadata().getClassName(), loader); } catch (LinkageError | ClassNotFoundException e) { if (log.isDebugEnabled()) { log.debug("Ignoring candidate class resource " + resource + " due to " + e); } return null; } catch (Throwable e) { if (log.isWarnEnabled()) { log.warn("Unexpected failure when loading class resource " + resource, e); } return null; } } /** * resources 转换为 Set * @param loader * @param resources * @return */ private Set> convert(ClassLoader loader, Resource[] resources){ Set> classSet = new HashSet<>(resources.length); for (Resource resource : resources){ Class clazz = loadClass(loader, resource); if (clazz != null){ classSet.add(clazz); } } return classSet; } }