拿到applicationContext,就能够调用getBean方法来得到Spring的bean对象了java
public class SpringContextUtil implements ApplicationContextAware { // Spring应用上下文环境 private static ApplicationContext applicationContext; /** * 实现ApplicationContextAware接口的回调方法,设置上下文环境 * * @param applicationContext */ public void setApplicationContext(ApplicationContext applicationContext) { SpringContextUtil.applicationContext = applicationContext; } /** * @return ApplicationContext */ public static ApplicationContext getApplicationContext() { return applicationContext; } /** * 获取对象 * * @param name * @return Object * @throws BeansException */ public static Object getBean(String name) throws BeansException { return applicationContext.getBean(name); } }
关键说明,spring
private T injectExtension(T instance) { try { if (objectFactory != null) { for (Method method : instance.getClass().getMethods()) { if (method.getName().startsWith("set") && method.getParameterTypes().length == 1 && Modifier.isPublic(method.getModifiers())) { Class<?> pt = method.getParameterTypes()[0]; try { String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : ""; Object object = objectFactory.getExtension(pt, property); if (object != null) { method.invoke(instance, object); } } catch (Exception e) { logger.error("fail to inject via method " + method.getName() + " of interface " + type.getName() + ": " + e.getMessage(), e); } } } } } catch (Exception e) { logger.error(e.getMessage(), e); } return instance; }
经过上面的方法,就能够将属性注入到instance中,实现自动装配(IOC)。下面咱们来看一下 objectFactory.getExtension(pt, property)是如何工做的。
上篇文章中,提到在获取Container扩展点接口对应的ExtensionLoader的时候,会执行私有ExtensionLoader构造函数。
private ExtensionLoader(Class<?> type) { this.type = type; objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()); }
由于此时type是Container.class,即objectFactory = ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension(); 当type为ExtensionFactory.class时,即 objectFactory = null. 咱们能够看出,全部非ExtensionFactory.class扩展点接口都会执行ExtensionFactory对应的ExtensionLoader实例的getAdaptiveExtension()方法返回一个ExtensionFactory实例,即objectFactory对象。不然,objectFactory对象为null。
getAdaptiveExtension 获取带有Adaptive注解的扩展实现类缓存
createAdaptiveExtension()建立实例app
injectExtension() 自动注入IOC函数
getAdaptiveExtensionClass() ---执行cachedAdaptiveClass对象的构造函数this
getExtensionClasses() ---解析全部的扩展点实现code
loadExtensionClasses() ---加载扩展类对象
ExtensionFactory的实现类AdaptiveExtensionFactory带有Adaptive标签,另外两个实现类SpiExtensionFactory、SpringExtensionFactory就是正常的实现类,也是咱们见的最多的那种扩展点实现类。接口
### AdaptiveExtensionFactory源码 关键说明, 1. factories属性,全部的非@Adaptive类的ExtensionFactory实例的集合,之后全部与ExtensionFactory打交道的操做都交给AdaptiveExtensionFactory, 2. injectExtension方法中,调用的 Object object = objectFactory.getExtension(pt, property);分别调用SpiExtensionFactory、SpringExtensionFactory两个实际的实现类。 /** * AdaptiveExtensionFactory * * @author william.liangf */ @Adaptive public class AdaptiveExtensionFactory implements ExtensionFactory { //全部的非@Adaptive类的ExtensionFactory实例的集合 private final List<ExtensionFactory> factories; //由于ExtensionFactory对应的ExtensionLoader实例中缓存字段已经初始化好了,因此的ExtensionLoader的操做大都是从缓存中获取的数据 public AdaptiveExtensionFactory() { //从缓存的static变量EXTENSION_LOADERS中拿到ExtensionFactory对应的ExtensionLoader实例 ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class); List<ExtensionFactory> list = new ArrayList<ExtensionFactory>(); //拿到loader中加载的普通的SPI扩展接口实现类的名称,spring与spi // adaptive=com.alibaba.dubbo.common.extension.factory.AdaptiveExtensionFactory // spi=com.alibaba.dubbo.common.extension.factory.SpiExtensionFactory for (String name : loader.getSupportedExtensions()) { //根据名称建立对应的ExtensionFactory实例 list.add(loader.getExtension(name)); } factories = Collections.unmodifiableList(list); } public <T> T getExtension(Class<T> type, String name) { for (ExtensionFactory factory : factories) { T extension = factory.getExtension(type, name); if (extension != null) { return extension; } } return null; } }
public class SpringExtensionFactory implements ExtensionFactory { private static final Set<ApplicationContext> contexts = new ConcurrentHashSet<ApplicationContext>(); public static void addApplicationContext(ApplicationContext context) { contexts.add(context); } public static void removeApplicationContext(ApplicationContext context) { contexts.remove(context); } @SuppressWarnings("unchecked") public <T> T getExtension(Class<T> type, String name) { for (ApplicationContext context : contexts) { if (context.containsBean(name)) { Object bean = context.getBean(name); if (type.isInstance(bean)) { return (T) bean; } } } return null; } }
是否是有一点熟悉的味道了啊,这也算是一个首尾呼应吧~rem
这一篇到时很快就写完了~ 下篇文章会讲解扩展点是如何实现AOP的。