查找组件的过程是调用DefaultCamelContext中的getComponent(String name)方法来完成的,至于该方法什么时候被调用,调用该方法真正目的是什么在后面讲解Camel运行原理时说明,为什么要先要讲清楚组件的查找过程,也是为讲解Camel运行原理做准备的。下面是getComponent(String name)方法源码:
public Component getComponent(String name) { //调用重载方法 return getComponent(name, autoCreateComponents); } public Component getComponent(String name, boolean autoCreateComponents) { synchronized (components) { //先根据名称在components这个Map中查找 Component component = components.get(name); //如果没有找到并且要自动创建组件 if (component == null && autoCreateComponents) { try { if (log.isDebugEnabled()) { log.debug("Using ComponentResolver: {} to resolve component with name: {}", getComponentResolver(), name); } //获取组件解析器根据组件名称进行解析,返回组件 component = getComponentResolver().resolveComponent(name, this); if (component != null) { addComponent(name, component); if (isStarted() || isStarting()) { // 组件返回后,如果是实现了Service接口,则调用startService方法 if (component instanceof Service) { startService((Service)component); } } } } catch (Exception e) { throw new RuntimeCamelException("Cannot auto create component: " + name, e); } } log.trace("getComponent({}) -> {}", name, component); return component; } }
public Component resolveComponent(String name, CamelContext context) { Object bean = null; try { //先在注册表中进行查找 bean = context.getRegistry().lookupByName(name); getLog().debug("Found component: {} in registry: {}", name, bean); } catch (Exception e) { getLog().debug("Ignored error looking up bean: " + name, e); } if (bean != null) { if (bean instanceof Component) {//如果在注册表中找到了组件则直接返回 return (Component) bean; } else { //如果不是Component类型则尝试进行转化 Component component = CamelContextHelper.convertTo(context, Component.class, bean); if (component != null) { return component; } } // we do not throw the exception here and try to auto create a component } // not in registry then use component factory Class<?> type; try {//注册表中没有找到则调用findComponent方法 type = findComponent(name, context); if (type == null) { // not found return null; } } catch (NoFactoryAvailableException e) { return null; } catch (Exception e) { throw new IllegalArgumentException("Invalid URI, no Component registered for scheme: " + name, e); } if (getLog().isDebugEnabled()) { getLog().debug("Found component: {} via type: {} via: {}{}", new Object[]{name, type.getName(), factoryFinder.getResourcePath(), name}); } //根据获取的组件Class类型,利用反射创建出其实例 if (Component.class.isAssignableFrom(type)) { return (Component) context.getInjector().newInstance(type); } else { throw new IllegalArgumentException("Type is not a Component implementation. Found: " + type.getName()); } }
private Class<?> findComponent(String name, CamelContext context) throws ClassNotFoundException, IOException { if (factoryFinder == null) { factoryFinder = context.getFactoryFinder(RESOURCE_PATH); } return factoryFinder.findClass(name); }
public Class<?> findClass(String key) throws ClassNotFoundException, IOException { return findClass(key, null); } public Class<?> findClass(String key, String propertyPrefix) throws ClassNotFoundException, IOException { //参数key就是组件名称,propertyPrefix为null,所以最后prefix就为一空字符串 String prefix = propertyPrefix != null ? propertyPrefix : ""; //重classMap中进行查找 Class<?> clazz = classMap.get(prefix + key); if (clazz == null) {//没有找到则调用newInstance方法 clazz = newInstance(doFindFactoryProperties(key), prefix); if (clazz != null) {//放入calssMap中缓存起来 classMap.put(prefix + key, clazz); } } return clazz; }
private Properties doFindFactoryProperties(String key) throws IOException { //path就是获取FactoryFinder时传入的资源路径,即META-INF/services/org/apache/camel/component/ //key就是组件名称 String uri = path + key; //根据uri把资源流返回,所以就是在类路径META-INF/services/org/apache/camel/component/下的一个名为key的文件(其实就是一properits文件)读取出来 InputStream in = classResolver.loadResourceAsStream(uri); if (in == null) { throw new NoFactoryAvailableException(uri); } // lets load the file BufferedInputStream reader = null; try { reader = IOHelper.buffered(in); Properties properties = new Properties(); //文件内容读取properties文件中,包含了组件名称与组件类型映射关系 properties.load(reader); return properties; } finally { IOHelper.close(reader, key, null); IOHelper.close(in, key, null); } }
private Class<?> newInstance(Properties properties, String propertyPrefix) throws ClassNotFoundException, IOException { String className = properties.getProperty(propertyPrefix + "class"); if (className == null) { throw new IOException("Expected property is missing: " + propertyPrefix + "class"); } Class<?> clazz = classResolver.resolveClass(className); if (clazz == null) { throw new ClassNotFoundException(className); } return clazz; }
原文地址:http://blog.csdn.net/xtayfjpk/article/details/39100919