首页  

SpringFactoriesLoader 简介     所属分类 springboot 浏览量 917
BootstrapClassLoader  ExtClassLoader AppClassLoader
分别加载Java核心类库 扩展类库以及应用的类路径( CLASSPATH)下的类库

双亲委派模型
先交给父加载器加载,只有当父加载器无法加载时,才尝试自己来加载
保证Java 核心库的类型安全




protected Class<?> loadClass(String name, boolean resolve) {
    synchronized (getClassLoadingLock(name)) {
    // 检查类是否已经被加载 
    Class<?> c = findLoadedClass(name);
    if (c == null) {
        try {
            // 双亲委派模型,先递归从父加载器加载
            if (parent != null) {
                c = parent.loadClass(name, false);
            } else {
                c = findBootstrapClassOrNull(name);
            }
        } catch (ClassNotFoundException e) {}
        if (c == null) {
            // 加载不到,通过findClass加载
            // 自定义类加载器,重写 findClass方法 
           c = findClass(name);
        }
    }
    if (resolve) {
        resolveClass(c);
    }
    return c;
    }
}

ServiceProviderInterface SPI
JDBC JNDI JAXP 

线程上下文类加载器 ContextClassLoader
Java应用的线程的上下文类加载器默认就是AppClassLoader

jdbc 驱动加载

java.sql.Driver
java.util.ServiceLoader.load(Class<Driver>)
loadInitialDrivers()
ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);

public static <S> ServiceLoader<S> load(Class<S> service) {
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    return ServiceLoader.load(service, cl);
}

Thread.currentThread().getContextClassLoader()
  
java.lang.ClassLoader.getResources(String)
public Enumeration<URL> getResources(String name) throws IOException 

public static Enumeration<URL> getSystemResources(String name) throws IOException
        
注意!!!
getSystemResources 静态方法
getResources 实例方法

 
String name = "a/b/Xxx.class";
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(name);
while (urls.hasMoreElements()) {
    URL url = urls.nextElement();
    System.out.println(url.toString());
}
    
    


SpringFactoriesLoader
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

classLoader.getResources(FACTORIES_RESOURCE_LOCATION)
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION)

UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                
LinkedMultiValueMap
             

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        MultiValueMap<String, String> result = cache.get(classLoader);
        if (result != null)
            return result;
        try {
            Enumeration<URL> urls = (classLoader != null ?
                    classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
            result = new LinkedMultiValueMap<>();
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                for (Map.Entry<?, ?> entry : properties.entrySet()) {
                    List<String> factoryClassNames = Arrays.asList(
                            StringUtils.commaDelimitedListToStringArray((String) entry.getValue()));
                    result.addAll((String) entry.getKey(), factoryClassNames);
                }
            }
            cache.put(classLoader, result);
            return result;
        }
        catch (IOException ex) {
            throw new IllegalArgumentException("Unable to load factories from location [" +
                    FACTORIES_RESOURCE_LOCATION + "]", ex);
        }
}


META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration\



file:/Users/dyyx/work/springboothello/target/classes/META-INF/spring.factories jar:file:/Users/dyyx/m2/org/springframework/spring-beans/5.0.4.RELEASE/spring-beans-5.0.4.RELEASE.jar!/META-INF/spring.factories jar:file:/Users/dyyx/m2/org/springframework/boot/spring-boot/2.0.0.RELEASE/spring-boot-2.0.0.RELEASE.jar!/META-INF/spring.factories jar:file:/Users/dyyx/m2/org/springframework/boot/spring-boot-autoconfigure/2.0.0.RELEASE/spring-boot-autoconfigure-2.0.0.RELEASE.jar!/META-INF/spring.factories jar:file:/Users/dyyx/m2/org/springframework/boot/spring-boot-actuator-autoconfigure/2.0.0.RELEASE/spring-boot-actuator-autoconfigure-2.0.0.RELEASE.jar!/META-INF/spring.factories jar:file:/Users/dyyx/m2/org/mybatis/spring/boot/mybatis-spring-boot-autoconfigure/1.3.2/mybatis-spring-boot-autoconfigure-1.3.2.jar!/META-INF/spring.factories

上一篇     下一篇
SpringIoC容器要点

JavaConfig与常见的Annotation

spring容器事件机制

Springboot自动配置原理简介

spring security 模块简介

Spring实战第四版保护Web应用笔记