关于kettle初始化的那点事

1. KettleEnvironment.init()详解

在Kettle的客户端工具,如Spoon、Pan、Kitchen、Carte等的源码中,都会有如下调用:

KettleEnvironment.init()

这篇文章主要从源码的层面分析这个方法具体干了些什么。

kettle源码使用5.3版本。

1.1 KettleEnvironment.init()初始化流程分析

(1) 首先判断KettleClientEnvironment是否初始化,没初始化的话就调用

KettleClientEnvironment.init()

进行初始化。该方法完成的动作主要是:

  • 创建.kettle文件夹及kettle.properties(不存在的话)
  • 读取kettle.properties的配置
  • 初始化KettleLogStore
  • 加载部分plugin,并在PluginRegistry中注册这些plugin

其中加载plugin的代码如下所示:

  1. // Load value meta data plugins
  2. //
  3. PluginRegistry.addPluginType( LoggingPluginType.getInstance() );
  4. PluginRegistry.addPluginType( ValueMetaPluginType.getInstance() );
  5. PluginRegistry.addPluginType( DatabasePluginType.getInstance() );
  6. PluginRegistry.addPluginType( ExtensionPointPluginType.getInstance() );
  7. PluginRegistry.addPluginType( TwoWayPasswordEncoderPluginType.getInstance() );
  8. PluginRegistry.init( true );

(2) 判断是否需要初始化JDNI,如果需要就调用

JndiUtil.initJNDI();

来初始化JNDI。

(3) 继续加载剩余的plugin,并在PluginRegistry中注册这些plugin,加载的plugin如下所示:

  1. // Register the native types and the plugins for the various plugin types...
  2. //
  3. PluginRegistry.addPluginType( RowDistributionPluginType.getInstance() );
  4. PluginRegistry.addPluginType( StepPluginType.getInstance() );
  5. PluginRegistry.addPluginType( PartitionerPluginType.getInstance() );
  6. PluginRegistry.addPluginType( JobEntryPluginType.getInstance() );
  7. PluginRegistry.addPluginType( LogTablePluginType.getInstance() );
  8. PluginRegistry.addPluginType( RepositoryPluginType.getInstance() );
  9. PluginRegistry.addPluginType( LifecyclePluginType.getInstance() );
  10. PluginRegistry.addPluginType( KettleLifecyclePluginType.getInstance() );
  11. PluginRegistry.addPluginType( ImportRulePluginType.getInstance() );
  12. PluginRegistry.addPluginType( CartePluginType.getInstance() );
  13. PluginRegistry.addPluginType( CompressionPluginType.getInstance() );
  14. PluginRegistry.addPluginType( AuthenticationProviderPluginType.getInstance() );
  15. PluginRegistry.addPluginType( AuthenticationConsumerPluginType.getInstance() );
  16. PluginRegistry. init();

(4) 初始化kettle变量,通过调用

KettleVariablesList.init()

来初始化kettle-variables.xml里面的kettle变量。

(5) 初始化调用注册的KettleLifecyclePluginType插件类型的监听器,并将这些监听器注册到JVM关闭钩子上,这体现在方法initLifecycleListeners()里。

(6) 完成流程(1)至(5) 之后 KettleEnvironment就算初始化成功了。

1.2 PluginRegistry.init()流程分析

这个方法会间接调用该类的init( boolean keepCache )方法。主要作用是为了完成所有插件类的动态加载(加载到classpath)。

核心代码片段如下:

  1. for ( final PluginTypeInterface pluginType : pluginTypes ) {
  2. log.snap( Metrics.METRIC_PLUGIN_REGISTRY_PLUGIN_TYPE_REGISTRATION_START, pluginType.getName() );
  3. registry.registerType( pluginType );
  4. log.snap( Metrics.METRIC_PLUGIN_REGISTRY_PLUGIN_TYPE_REGISTRATION_STOP, pluginType.getName() );
  5. }

对于每一种插件类型PluginTypeInterface都需要调用:

registry.registerType( pluginType )

registerType()方法会调用

pluginType.searchPlugins()

来寻找该类型插件的所有插件。

Tip:

PluginRegistry.init()方法还会加载KETTLE_PLUGIN_CLASSES配置项中的插件,多个插件以逗号隔开。通常都是在开发debug模式才用这个配置项来加载需要测试的插件。

searchPlugins()方法默认会搜索3种类型的插件:

(1) 内置插件(registerNatives)

registerNatives();

(2) 注解插件(registerPluginJars)

registerPluginJars();

(3) xml配置的外置插件(registerXmlPlugins)

registerXmlPlugins();

eg:

(1) StepPluginTyperegisterNatives方法会遍历加载kettle内置的kettle-steps.xml中所有的step组件,然后通过调用:

registry.registerPlugin( pluginType, pluginInterface )

将组件注册到PluginRegistry。

(2) registerPluginJars方法会从以下文件夹加载jar包:

  • plugins/
  • {kettle.dir}/plugins/

如果jar包中含有该插件类型的注解来修饰一个插件类,那么该插件类将被注册到PluginRegistry。

(3) registerXmlPlugins方法会从特定文件夹下去加载plugin.xml文件:

  • plugins/steps/
  • {kettle.dir}/plugins/steps/

并从该文件中获取对应的插件并注册到PluginRegistry。

Tip:

PluginRegistry维护一个HashMap来存放注册的组件(pluginMap),其中key是每一种插件类型,value保存该插件类型的所有插件类集合(List)。

1.3 总结

(1) 在KettleEnvironment.init()方法里面主要实现了Kettle各种插件类型插件的动态加载以及注册到PluginRegistry。这个方法将所有插件动态加载到项目的classpath中,包括插件依赖的jar包。

(2) 如果开发kettle客户端程序,那么首要调用的方法肯定是KettleEnvironment.init()


转载自:http://blog.csdn.net/d6619309/article/details/50654355

你可能感兴趣的:(kettle源代码部署)