查找组件的过程是调用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