想要了解springboot加载配置文件,要了解观察者模式,以及相应的实现方式
1、观察者模式(Publish/Subscribe):
举例说明:
报社方负责出版报纸.
你订阅了该报社的报纸,那么只要报社发布了新报纸,就会通知你,或发到你手上.
如果你不想再读报纸,可以取消订阅,这样,报社发布了新报纸就不会再通知你.
jdk不仅提供了Observable类、Observer接口支持观察者模式,而且也提供了EventObject类、EventListener接口来支持事件监听模式,
虽然两者属于同一类型模式,都属于回调机制,主动推送消息,但使用场景有些区别。
1. 事件-监听机制
2. 观察者模式
观察者(Observer)相当于事件监听者(监听器),被观察者(Observable)相当于事件源和事件,执行逻辑时通知observer即可触发oberver的update,同时 可传被观察者和参数。简化了事件-监听模式的实现
连接为设计模式
package com.ctrip.framework.apollo.configservice;import com.ctrip.framework.apollo.biz.ApolloBizConfig;import com.ctrip.framework.apollo.common.ApolloCommonConfig;import com.ctrip.framework.apollo.metaservice.ApolloMetaServiceConfig;import java.lang.reflect.Constructor;import java.net.URL;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.Enumeration;import java.util.LinkedHashSet;import java.util.List;import java.util.Map;import java.util.Properties;import java.util.Set;import org.springframework.beans.BeanUtils;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;import org.springframework.context.ApplicationContextInitializer;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.EnableAspectJAutoProxy;import org.springframework.context.annotation.PropertySource;import org.springframework.core.io.UrlResource;import org.springframework.core.io.support.PropertiesLoaderUtils;import org.springframework.core.io.support.SpringFactoriesLoader;import org.springframework.transaction.annotation.EnableTransactionManagement;import org.springframework.util.Assert;import org.springframework.util.ClassUtils;import org.springframework.util.ConcurrentReferenceHashMap;import org.springframework.util.LinkedMultiValueMap;import org.springframework.util.MultiValueMap;import org.springframework.util.StringUtils;/** * Spring boot application entry point * * @author Jason Song(song_s@ctrip.com) */@EnableEurekaServer@EnableAspectJAutoProxy@EnableAutoConfiguration // (exclude = EurekaClientConfigBean.class)@Configuration@EnableTransactionManagement@PropertySource(value = {"classpath:configservice.properties"})@ComponentScan(basePackageClasses = {ApolloCommonConfig.class, ApolloBizConfig.class, ConfigServiceApplication.class, ApolloMetaServiceConfig.class})public class ConfigServiceApplication { private static final Map> cache = new ConcurrentReferenceHashMap<>(); public static void main(String[] args) throws Exception { ClassLoader classloader = ConfigServiceApplication.class.getClassLoader(); Enumeration urls = classloader.getResources("META-INF/spring.factories") ; MultiValueMap 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 factoryClassNames = Arrays.asList(StringUtils.commaDelimitedListToStringArray((String) entry.getValue())); result.addAll((String) entry.getKey(), factoryClassNames); } } cache.put(classloader, result); String factoryClassName = ApplicationContextInitializer.class.getName(); result.getOrDefault(factoryClassName, Collections.emptyList()); Set names = new LinkedHashSet<>(result.getOrDefault(factoryClassName, Collections.emptyList())); System.out.println(names); for (String name : names) { Class instanceClass = ClassUtils.forName(name, classloader); Assert.isAssignable(ApplicationContextInitializer.class, instanceClass); Constructor constructor = instanceClass.getDeclaredConstructor(parameterTypes); BeanUtils.instantiateClass(constructor, args); Object instance = (Object) BeanUtils.instantiateClass(constructor, args); } SpringApplication.run(ConfigServiceApplication.class, args); } @SuppressWarnings("unchecked") private List createSpringFactoriesInstances(Class type, Class [] parameterTypes, ClassLoader classLoader, Object[] args, Set names) { List instances = new ArrayList<>(names.size()); for (String name : names) { try { Class instanceClass = ClassUtils.forName(name, classLoader); Assert.isAssignable(type, instanceClass); Constructor constructor = instanceClass.getDeclaredConstructor(parameterTypes); T instance = (T) BeanUtils.instantiateClass(constructor, args); instances.add(instance); } catch (Throwable ex) { throw new IllegalArgumentException( "Cannot instantiate " + type + " : " + name, ex); }; } return instances; }}