Camel component search method

Source: Internet
Author: User
In the preceding camel example, The from and to method of routebuilder is called in the routing construction. The parameter of this method is a URI string. Camel running is organized by components, and the parameter we pass is a string, so camel needs to find the corresponding component based on this URI string, maintain the URI ing between Uris and components.

The component search process is completed by calling the getcomponent (string name) method in defaultcamelcontext. When is this method called, what is the real purpose of calling this method? I will explain the camel running principle in the following sections. Why should I first explain the component search process and prepare for explaining the camel running principle. The following is the source code of the getcomponent (string name) method:


Public component getcomponent (string name) {// call the overload method return getcomponent (name, autocreatecomponents);} public component getcomponent (string name, Boolean autocreatecomponents) {synchronized (components) {// search for component Component = components in the map by name. get (name); // if no component is found and you want to automatically create the component if (Component = NULL & autocreatecomponents) {try {If (log. isdebugenabled () {log. debug ("using compone Ntresolver :{}to resolve component with name :{} ", getcomponentresolver (), name) ;}// gets the component Parser for parsing Based on the component name, returns component Component = getcomponentresolver (). resolvecomponent (name, this); If (Component! = NULL) {addcomponent (name, component); If (isstarted () | isstarting () {// After the component returns, if the service interface is implemented, call the startservice method 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 ;}}

The synchronized keyword is used in the preceding method. Of course, this is for thread synchronization. Because camelcontext can run multiple routes, while camelcontext is for Singleton, the member variable components has concurrent access to multiple threads. The keyword synchronized is used to avoid repeated component creation.

Now let's look at the resolvecomponent method. The following is the source code of the defaultcomponentresolver resolvecomponent method:

Public component resolvecomponent (string name, camelcontext context) {object bean = NULL; try {// search for bean = context in the Registry first. 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) {// If a component is found in the registry, return (Component) bean ;} else {// if it is not of the component type, try to convert component Component = camelcontexthelper. convertize (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 {// The findcomponent method type = findcomponent (name, context) is called if not found in the registry; 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});} // you can use reflection to create an IF (component. class. isassignablefrom (type) {return (Component) context. getinjector (). newinstance (type);} else {Throw new illegalargumentexception ("type is not a component implementation. found: "+ type. getname ());}}

In the above method, there are two methods for searching components. One is to search in the registry, and the result is directly returned if the component type instance is found, if not, convert the data. Second, call the findcomponent method to continue searching. The findcomponent method source code is as follows:

private Class<?> findComponent(String name, CamelContext context) throws ClassNotFoundException, IOException {    if (factoryFinder == null) {        factoryFinder = context.getFactoryFinder(RESOURCE_PATH);    }    return factoryFinder.findClass(name);}

First obtain a factoryfinder instance according to the resource path, and then call its findclass method, where resource_path is a constant, the value is META-INF/services/org/Apache/camel/component/
You can see that this is based on the resources in a specific path of the class path. The process of obtaining a factoryfinder instance is simple. factoryfinder is an interface that returns the real type defaultfactoryfinder. The following is the findclass method source code of defafacfactoryfinder:
Public class <?> Findclass (string key) throws classnotfoundexception, ioexception {return findclass (Key, null);} public class <?> Findclass (string key, string propertyprefix) throws classnotfoundexception, ioexception {// The parameter key is the component name, And propertyprefix is null, so the final prefix is an empty string prefix = propertyprefix! = NULL? Propertyprefix: ""; // search for class in heavy classmap <?> Clazz = classmap. get (prefix + key); If (clazz = NULL) {// The newinstance method clazz = newinstance (dofindfactoryproperties (key), prefix) is called if (clazz! = NULL) {// put it in calssmap and cache it. classmap. Put (prefix + key, clazz) ;}} return clazz ;}

The newinstance method requires a properties object, which rotates the ing between the component name and the component type (calss). The following is the source code of the dofindfactoryproperties method:

Private Properties dofindfactoryproperties (string key) throws ioexception {// path is the resource path passed in when factoryfinder is obtained, that is, the META-INF/services/org/Apache/camel/component // key is the component name string uri = path + key; // return the resource stream according to the URI, so it is in the class path META-INF/services/org/Apache/camel/component/under a file named key (in fact, is a properits file) read out 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 (); // The file content is read from the properties file, which contains the ing between the component name and the component type properties. load (Reader); return properties;} finally {iohelper. close (reader, key, null); iohelper. close (in, key, null );}}

The newinstance method source code is as follows:

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;}

This method is easy to obtain the value of key as class, and the value is of the component type.

Based on the above, there are two ways to obtain component instances:
A. search in the registry
B. get it from a properties file with the same name as the component name in the class path META-INF/services/org/Apache/camel/component/
Both methods cache the component after it is found to avoid repeated searches.

At this point, the component name is parsed Based on the URI, and the process of getting the component instance from the component name should be clear. As for the function of finding the component, when will it be called, I will explain it again next time.

Camel component search method

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.