You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2020/10/19 06:51:43 UTC

[shardingsphere-elasticjob] branch master updated: Create ExtraJobConfiguration to unify Job Configuration (#1592)

This is an automated email from the ASF dual-hosted git repository.

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere-elasticjob.git


The following commit(s) were added to refs/heads/master by this push:
     new 30fc9c4  Create ExtraJobConfiguration to unify Job Configuration (#1592)
30fc9c4 is described below

commit 30fc9c43ed0b1e2ce3596a7b6e6e6f1393d989c8
Author: Liang Zhang <te...@163.com>
AuthorDate: Mon Oct 19 14:51:32 2020 +0800

    Create ExtraJobConfiguration to unify Job Configuration (#1592)
    
    * Add JobExtraConfiguration
    
    * Refactor TracingConfiguration to implement ExtraConfiguration
    
    * Add ErrorHandlerConfiguration and implement ExtraConfiguration
---
 .../elasticjob/api/JobConfiguration.java           | 18 ++++++-
 .../elasticjob/api/JobExtraConfiguration.java      | 17 ++-----
 .../error/handler/ErrorHandlerConfiguration.java   | 19 ++------
 .../elasticjob/error/handler/JobErrorHandler.java  |  8 ++--
 .../{config => }/DingtalkConfiguration.java        | 17 ++-----
 .../handler/dingtalk/DingtalkJobErrorHandler.java  |  7 +--
 .../config/DingtalkPropertiesConstants.java        | 40 ----------------
 .../dingtalk/DingtalkJobErrorHandlerTest.java      | 31 ++++--------
 .../email/{config => }/EmailConfiguration.java     | 23 ++-------
 .../error/handler/email/EmailJobErrorHandler.java  |  6 +--
 .../email/config/EmailPropertiesConstants.java     | 50 -------------------
 .../handler/email/EmailJobErrorHandlerTest.java    | 20 ++------
 .../handler/general/IgnoreJobErrorHandler.java     |  7 ++-
 .../error/handler/general/LogJobErrorHandler.java  |  7 ++-
 .../handler/general/ThrowJobErrorHandler.java      |  7 ++-
 .../handler/general/IgnoreJobErrorHandlerTest.java |  7 ++-
 .../handler/general/LogJobErrorHandlerTest.java    |  3 +-
 .../handler/general/ThrowJobErrorHandlerTest.java  |  7 ++-
 ...tiesConstants.java => WechatConfiguration.java} | 24 +++++-----
 .../handler/wechat/WechatJobErrorHandler.java      |  7 +--
 .../handler/wechat/config/WechatConfiguration.java | 41 ----------------
 .../handler/wechat/WechatJobErrorHandlerTest.java  | 18 ++-----
 .../elasticjob/executor/ElasticJobExecutor.java    | 18 ++++---
 .../api/bootstrap/impl/OneOffJobBootstrap.java     | 13 +----
 .../api/bootstrap/impl/ScheduleJobBootstrap.java   | 13 +----
 .../lite/internal/schedule/JobScheduler.java       | 11 +++--
 .../boot/job/ElasticJobLiteAutoConfiguration.java  | 36 +++++++++-----
 .../job/parser/JobBeanDefinitionParser.java        | 36 ++++----------
 .../namespace/job/tag/JobBeanDefinitionTag.java    |  2 +
 .../resources/META-INF/job/withEventTraceRdb.xml   |  3 +-
 elasticjob-tracing/elasticjob-tracing-api/pom.xml  |  6 +++
 .../tracing/api/TracingConfiguration.java          |  3 +-
 .../elasticjob/lite/example/JavaMain.java          | 56 ++++++++--------------
 33 files changed, 177 insertions(+), 404 deletions(-)

diff --git a/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobConfiguration.java b/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobConfiguration.java
index 326cf01..6c21d55 100644
--- a/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobConfiguration.java
+++ b/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobConfiguration.java
@@ -27,6 +27,7 @@ import lombok.RequiredArgsConstructor;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.Properties;
 
 /**
@@ -64,6 +65,8 @@ public final class JobConfiguration {
     
     private final Collection<String> jobListenerTypes;
     
+    private final Collection<JobExtraConfiguration> extraConfigurations;
+    
     private final String description;
     
     private final Properties props;
@@ -113,6 +116,8 @@ public final class JobConfiguration {
         private String jobErrorHandlerType;
     
         private final Collection<String> jobListenerTypes = new ArrayList<>();
+
+        private final Collection<JobExtraConfiguration> extraConfigurations = new LinkedList<>();
         
         private String description = "";
         
@@ -296,6 +301,17 @@ public final class JobConfiguration {
         }
         
         /**
+         * Add extra configurations.
+         *
+         * @param extraConfig job extra configuration
+         * @return job configuration builder
+         */
+        public Builder addExtraConfigurations(final JobExtraConfiguration extraConfig) {
+            extraConfigurations.add(extraConfig);
+            return this;
+        }
+        
+        /**
          * Set job description.
          *
          * @param description job description
@@ -360,7 +376,7 @@ public final class JobConfiguration {
             Preconditions.checkArgument(shardingTotalCount > 0, "shardingTotalCount should larger than zero.");
             return new JobConfiguration(jobName, cron, shardingTotalCount, shardingItemParameters, jobParameter, 
                     monitorExecution, failover, misfire, maxTimeDiffSeconds, reconcileIntervalMinutes,
-                    jobShardingStrategyType, jobExecutorServiceHandlerType, jobErrorHandlerType, jobListenerTypes, description, props, disabled, overwrite);
+                    jobShardingStrategyType, jobExecutorServiceHandlerType, jobErrorHandlerType, jobListenerTypes, extraConfigurations, description, props, disabled, overwrite);
         }
     }
 }
diff --git a/elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java b/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobExtraConfiguration.java
similarity index 70%
copy from elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java
copy to elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobExtraConfiguration.java
index c97bed6..4307260 100644
--- a/elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java
+++ b/elasticjob-api/src/main/java/org/apache/shardingsphere/elasticjob/api/JobExtraConfiguration.java
@@ -15,21 +15,10 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.elasticjob.tracing.api;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
+package org.apache.shardingsphere.elasticjob.api;
 
 /**
- * Tracing configuration.
- * 
- * @param <T> type of tracing storage
+ * Job extra configuration.
  */
-@RequiredArgsConstructor
-@Getter
-public final class TracingConfiguration<T> {
-    
-    private final String type;
-    
-    private final T storage;
+public interface JobExtraConfiguration {
 }
diff --git a/elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java b/elasticjob-error-handler/elasticjob-error-handler-spi/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/ErrorHandlerConfiguration.java
similarity index 70%
copy from elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java
copy to elasticjob-error-handler/elasticjob-error-handler-spi/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/ErrorHandlerConfiguration.java
index c97bed6..566939e 100644
--- a/elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-spi/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/ErrorHandlerConfiguration.java
@@ -7,7 +7,7 @@
  * the License.  You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
- *  
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,21 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.elasticjob.tracing.api;
+package org.apache.shardingsphere.elasticjob.error.handler;
 
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.elasticjob.api.JobExtraConfiguration;
 
 /**
- * Tracing configuration.
- * 
- * @param <T> type of tracing storage
+ * Error handler configuration.
  */
-@RequiredArgsConstructor
-@Getter
-public final class TracingConfiguration<T> {
-    
-    private final String type;
-    
-    private final T storage;
+public interface ErrorHandlerConfiguration extends JobExtraConfiguration {
 }
diff --git a/elasticjob-error-handler/elasticjob-error-handler-spi/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/JobErrorHandler.java b/elasticjob-error-handler/elasticjob-error-handler-spi/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/JobErrorHandler.java
index 95757b4..be77e50 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-spi/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/JobErrorHandler.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-spi/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/JobErrorHandler.java
@@ -19,19 +19,17 @@ package org.apache.shardingsphere.elasticjob.error.handler;
 
 import org.apache.shardingsphere.elasticjob.infra.spi.TypedSPI;
 
-import java.util.Properties;
-
 /**
  * Job error handler.
  */
-public interface JobErrorHandler extends TypedSPI {
+public interface JobErrorHandler<T extends ErrorHandlerConfiguration> extends TypedSPI {
     
     /**
      * Handle exception.
      * 
      * @param jobName job name
-     * @param props job properties
+     * @param config error handler configuration
      * @param cause failure cause
      */
-    void handleException(String jobName, Properties props, Throwable cause);
+    void handleException(String jobName, T config, Throwable cause);
 }
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/config/DingtalkConfiguration.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkConfiguration.java
similarity index 61%
rename from elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/config/DingtalkConfiguration.java
rename to elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkConfiguration.java
index dffc9a0..be30415 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/config/DingtalkConfiguration.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkConfiguration.java
@@ -15,17 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.elasticjob.error.handler.dingtalk.config;
+package org.apache.shardingsphere.elasticjob.error.handler.dingtalk;
 
 import lombok.Getter;
-
-import java.util.Properties;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.elasticjob.error.handler.ErrorHandlerConfiguration;
 
 /**
  * Job error handler configuration for send error message via dingtalk.
  */
+@RequiredArgsConstructor
 @Getter
-public final class DingtalkConfiguration {
+public final class DingtalkConfiguration implements ErrorHandlerConfiguration {
     
     private final String webhook;
     
@@ -36,12 +37,4 @@ public final class DingtalkConfiguration {
     private final int connectTimeoutMillisecond;
     
     private final int readTimeoutMillisecond;
-    
-    public DingtalkConfiguration(final Properties props) {
-        webhook = props.getProperty(DingtalkPropertiesConstants.WEBHOOK);
-        keyword = props.getProperty(DingtalkPropertiesConstants.KEYWORD);
-        secret = props.getProperty(DingtalkPropertiesConstants.SECRET);
-        connectTimeoutMillisecond = Integer.parseInt(props.getProperty(DingtalkPropertiesConstants.CONNECT_TIMEOUT_MILLISECOND, DingtalkPropertiesConstants.DEFAULT_CONNECT_TIMEOUT_MILLISECOND));
-        readTimeoutMillisecond = Integer.parseInt(props.getProperty(DingtalkPropertiesConstants.READ_TIMEOUT_MILLISECOND, DingtalkPropertiesConstants.DEFAULT_READ_TIMEOUT_MILLISECOND));
-    }
 }
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkJobErrorHandler.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkJobErrorHandler.java
index c08a294..010d2f0 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkJobErrorHandler.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkJobErrorHandler.java
@@ -30,7 +30,6 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandler;
-import org.apache.shardingsphere.elasticjob.error.handler.dingtalk.config.DingtalkConfiguration;
 import org.apache.shardingsphere.elasticjob.infra.json.GsonFactory;
 
 import javax.crypto.Mac;
@@ -46,13 +45,12 @@ import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
 import java.util.Base64;
 import java.util.Collections;
-import java.util.Properties;
 
 /**
  * Job error handler for send error message via dingtalk.
  */
 @Slf4j
-public final class DingtalkJobErrorHandler implements JobErrorHandler {
+public final class DingtalkJobErrorHandler implements JobErrorHandler<DingtalkConfiguration> {
     
     private final CloseableHttpClient httpclient = HttpClients.createDefault();
     
@@ -73,8 +71,7 @@ public final class DingtalkJobErrorHandler implements JobErrorHandler {
     }
     
     @Override
-    public void handleException(final String jobName, final Properties props, final Throwable cause) {
-        DingtalkConfiguration config = new DingtalkConfiguration(props);
+    public void handleException(final String jobName, final DingtalkConfiguration config, final Throwable cause) {
         HttpPost httpPost = createHTTPPostMethod(jobName, cause, config);
         try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
             int status = response.getStatusLine().getStatusCode();
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/config/DingtalkPropertiesConstants.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/config/DingtalkPropertiesConstants.java
deleted file mode 100644
index cfa07de..0000000
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/config/DingtalkPropertiesConstants.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *  
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.error.handler.dingtalk.config;
-
-/**
- * Job error handler properties constants for send error message via dingtalk.
- */
-public final class DingtalkPropertiesConstants {
-    
-    public static final String DEFAULT_CONNECT_TIMEOUT_MILLISECOND = "3000";
-    
-    public static final String DEFAULT_READ_TIMEOUT_MILLISECOND = "5000";
-    
-    private static final String PREFIX = "dingtalk.";
-    
-    public static final String WEBHOOK = PREFIX + "webhook";
-    
-    public static final String KEYWORD = PREFIX + "keyword";
-    
-    public static final String SECRET = PREFIX + "secret";
-    
-    public static final String CONNECT_TIMEOUT_MILLISECOND = PREFIX + "connectTimeoutMillisecond";
-    
-    public static final String READ_TIMEOUT_MILLISECOND = PREFIX + "readTimeoutMillisecond";
-}
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkJobErrorHandlerTest.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkJobErrorHandlerTest.java
index 3313e15..794b8d2 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkJobErrorHandlerTest.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-dingtalk/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/dingtalk/DingtalkJobErrorHandlerTest.java
@@ -19,7 +19,6 @@ package org.apache.shardingsphere.elasticjob.error.handler.dingtalk;
 
 import lombok.SneakyThrows;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandlerFactory;
-import org.apache.shardingsphere.elasticjob.error.handler.dingtalk.config.DingtalkPropertiesConstants;
 import org.apache.shardingsphere.elasticjob.error.handler.dingtalk.fixture.DingtalkInternalController;
 import org.apache.shardingsphere.elasticjob.infra.exception.JobConfigurationException;
 import org.apache.shardingsphere.elasticjob.restful.NettyRestfulService;
@@ -35,7 +34,6 @@ import org.slf4j.Logger;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.Properties;
 
 import static org.mockito.Mockito.verify;
 
@@ -72,7 +70,7 @@ public final class DingtalkJobErrorHandlerTest {
         DingtalkJobErrorHandler actual = getDingtalkJobErrorHandler();
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", createJobProperties("http://localhost:9875/send?access_token=mocked_token"), cause);
+        actual.handleException("test_job", createDingtalkConfiguration("http://localhost:9875/send?access_token=mocked_token"), cause);
         verify(log).info("An exception has occurred in Job '{}', Notification to Dingtalk was successful.", "test_job", cause);
     }
     
@@ -81,7 +79,7 @@ public final class DingtalkJobErrorHandlerTest {
         DingtalkJobErrorHandler actual = getDingtalkJobErrorHandler();
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", createJobProperties("http://localhost:9875/send?access_token=wrong_token"), cause);
+        actual.handleException("test_job", createDingtalkConfiguration("http://localhost:9875/send?access_token=wrong_token"), cause);
         verify(log).info("An exception has occurred in Job '{}', But failed to send alert by Dingtalk because of: {}", "test_job", "token is not exist", cause);
     }
     
@@ -90,7 +88,7 @@ public final class DingtalkJobErrorHandlerTest {
         DingtalkJobErrorHandler actual = getDingtalkJobErrorHandler();
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", createJobProperties("http://localhost:9875/404"), cause);
+        actual.handleException("test_job", createDingtalkConfiguration("http://localhost:9875/404"), cause);
         verify(log).error("An exception has occurred in Job '{}', But failed to send alert by Dingtalk because of: Unexpected response status: {}", "test_job", 404, cause);
     }
     
@@ -99,7 +97,7 @@ public final class DingtalkJobErrorHandlerTest {
         DingtalkJobErrorHandler actual = getDingtalkJobErrorHandler();
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", createNoSignJobProperties("http://wrongUrl"), cause);
+        actual.handleException("test_job", createNoSignJobDingtalkConfiguration("http://wrongUrl"), cause);
         verify(log).error("An exception has occurred in Job '{}', But failed to send alert by Dingtalk because of", "test_job", cause);
     }
     
@@ -108,7 +106,7 @@ public final class DingtalkJobErrorHandlerTest {
         DingtalkJobErrorHandler actual = getDingtalkJobErrorHandler();
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", createNoSignJobProperties("http://localhost:9875/send?access_token=mocked_token"), cause);
+        actual.handleException("test_job", createNoSignJobDingtalkConfiguration("http://localhost:9875/send?access_token=mocked_token"), cause);
         verify(log).info("An exception has occurred in Job '{}', Notification to Dingtalk was successful.", "test_job", cause);
     }
     
@@ -126,22 +124,11 @@ public final class DingtalkJobErrorHandlerTest {
         field.set(dingtalkJobErrorHandler, log);
     }
     
-    private Properties createJobProperties(final String webhook) {
-        Properties result = new Properties();
-        result.setProperty(DingtalkPropertiesConstants.WEBHOOK, webhook);
-        result.setProperty(DingtalkPropertiesConstants.KEYWORD, "mocked_keyword");
-        result.setProperty(DingtalkPropertiesConstants.SECRET, "mocked_secret");
-        result.setProperty(DingtalkPropertiesConstants.CONNECT_TIMEOUT_MILLISECOND, "4000");
-        result.setProperty(DingtalkPropertiesConstants.READ_TIMEOUT_MILLISECOND, "6000");
-        return result;
+    private DingtalkConfiguration createDingtalkConfiguration(final String webhook) {
+        return new DingtalkConfiguration(webhook, "mocked_keyword", "mocked_secret", 4000, 6000);
     }
     
-    private Properties createNoSignJobProperties(final String webhook) {
-        Properties result = new Properties();
-        result.setProperty(DingtalkPropertiesConstants.WEBHOOK, webhook);
-        result.setProperty(DingtalkPropertiesConstants.KEYWORD, "mocked_keyword");
-        result.setProperty(DingtalkPropertiesConstants.CONNECT_TIMEOUT_MILLISECOND, "4000");
-        result.setProperty(DingtalkPropertiesConstants.READ_TIMEOUT_MILLISECOND, "6000");
-        return result;
+    private DingtalkConfiguration createNoSignJobDingtalkConfiguration(final String webhook) {
+        return new DingtalkConfiguration(webhook, "mocked_keyword", null, 4000, 6000);
     }
 }
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/config/EmailConfiguration.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailConfiguration.java
similarity index 57%
rename from elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/config/EmailConfiguration.java
rename to elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailConfiguration.java
index 9db5c22..6f851e7 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/config/EmailConfiguration.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailConfiguration.java
@@ -15,17 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.elasticjob.error.handler.email.config;
+package org.apache.shardingsphere.elasticjob.error.handler.email;
 
 import lombok.Getter;
-
-import java.util.Properties;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.elasticjob.error.handler.ErrorHandlerConfiguration;
 
 /**
  * Job error handler configuration for send error message via email.
  */
+@RequiredArgsConstructor
 @Getter
-public final class EmailConfiguration {
+public final class EmailConfiguration implements ErrorHandlerConfiguration {
     
     private final String host;
     
@@ -48,18 +49,4 @@ public final class EmailConfiguration {
     private final String bcc;
     
     private final boolean debug;
-    
-    public EmailConfiguration(final Properties props) {
-        host = props.getProperty(EmailPropertiesConstants.HOST);
-        port = Integer.parseInt(props.getProperty(EmailPropertiesConstants.PORT));
-        username = props.getProperty(EmailPropertiesConstants.USERNAME);
-        password = props.getProperty(EmailPropertiesConstants.PASSWORD);
-        useSsl = Boolean.parseBoolean(props.getProperty(EmailPropertiesConstants.IS_USE_SSL, Boolean.FALSE.toString()));
-        subject = props.getProperty(EmailPropertiesConstants.SUBJECT, EmailPropertiesConstants.DEFAULT_SUBJECT);
-        from = props.getProperty(EmailPropertiesConstants.FROM);
-        to = props.getProperty(EmailPropertiesConstants.TO);
-        cc = props.getProperty(EmailPropertiesConstants.CC);
-        bcc = props.getProperty(EmailPropertiesConstants.BCC);
-        debug = Boolean.parseBoolean(props.getProperty(EmailPropertiesConstants.IS_DEBUG, Boolean.FALSE.toString()));
-    }
 }
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailJobErrorHandler.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailJobErrorHandler.java
index 7e575a1..d20fbb7 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailJobErrorHandler.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailJobErrorHandler.java
@@ -20,7 +20,6 @@ package org.apache.shardingsphere.elasticjob.error.handler.email;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandler;
-import org.apache.shardingsphere.elasticjob.error.handler.email.config.EmailConfiguration;
 
 import javax.mail.Authenticator;
 import javax.mail.BodyPart;
@@ -44,13 +43,12 @@ import java.util.Properties;
  * Job error handler for send error message via email.
  */
 @Slf4j
-public final class EmailJobErrorHandler implements JobErrorHandler {
+public final class EmailJobErrorHandler implements JobErrorHandler<EmailConfiguration> {
     
     private Session session;
     
     @Override
-    public void handleException(final String jobName, final Properties props, final Throwable cause) {
-        EmailConfiguration config = new EmailConfiguration(props);
+    public void handleException(final String jobName, final EmailConfiguration config, final Throwable cause) {
         String errorMessage = getErrorMessage(jobName, cause);
         try {
             sendMessage(createMessage(errorMessage, config), config);
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/config/EmailPropertiesConstants.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/config/EmailPropertiesConstants.java
deleted file mode 100644
index c9f47f7..0000000
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/email/config/EmailPropertiesConstants.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *  
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.error.handler.email.config;
-
-/**
- * Job error handler properties constants for send error message via email.
- */
-public final class EmailPropertiesConstants {
-    
-    public static final String DEFAULT_SUBJECT = "ElasticJob error message";
-    
-    private static final String PREFIX = "email.";
-    
-    public static final String HOST = PREFIX + "host";
-    
-    public static final String PORT = PREFIX + "port";
-    
-    public static final String USERNAME = PREFIX + "username";
-    
-    public static final String PASSWORD = PREFIX + "password";
-    
-    public static final String IS_USE_SSL = PREFIX + "useSsl";
-    
-    public static final String SUBJECT = PREFIX + "subject";
-    
-    public static final String FROM = PREFIX + "from";
-    
-    public static final String TO = PREFIX + "to";
-    
-    public static final String CC = PREFIX + "cc";
-    
-    public static final String BCC = PREFIX + "bcc";
-    
-    public static final String IS_DEBUG = PREFIX + "debug";
-}
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailJobErrorHandlerTest.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailJobErrorHandlerTest.java
index f4cd111..ad90299 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailJobErrorHandlerTest.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-email/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/email/EmailJobErrorHandlerTest.java
@@ -19,7 +19,6 @@ package org.apache.shardingsphere.elasticjob.error.handler.email;
 
 import lombok.SneakyThrows;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandlerFactory;
-import org.apache.shardingsphere.elasticjob.error.handler.email.config.EmailPropertiesConstants;
 import org.apache.shardingsphere.elasticjob.infra.exception.JobConfigurationException;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -29,7 +28,6 @@ import org.slf4j.Logger;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.Properties;
 
 import static org.mockito.Mockito.verify;
 
@@ -44,7 +42,7 @@ public final class EmailJobErrorHandlerTest {
         EmailJobErrorHandler emailJobErrorHandler = getEmailJobErrorHandler();
         setStaticFieldValue(emailJobErrorHandler, "log", log);
         Throwable cause = new RuntimeException("test");
-        emailJobErrorHandler.handleException("test_job", createJobProperties(), cause);
+        emailJobErrorHandler.handleException("test_job", createEmailConfiguration(), cause);
         verify(log).error("An exception has occurred in Job '{}', But failed to send alert by email because of", "test_job", cause);
     }
     
@@ -62,19 +60,7 @@ public final class EmailJobErrorHandlerTest {
         fieldLog.set(wechatJobErrorHandler, value);
     }
     
-    private Properties createJobProperties() {
-        Properties result = new Properties();
-        result.setProperty(EmailPropertiesConstants.HOST, "xxx");
-        result.setProperty(EmailPropertiesConstants.PORT, "465");
-        result.setProperty(EmailPropertiesConstants.USERNAME, "xxx");
-        result.setProperty(EmailPropertiesConstants.PASSWORD, "xxx");
-        result.setProperty(EmailPropertiesConstants.IS_USE_SSL, "true");
-        result.setProperty(EmailPropertiesConstants.SUBJECT, "Unit test notification");
-        result.setProperty(EmailPropertiesConstants.FROM, "from@xxx.com");
-        result.setProperty(EmailPropertiesConstants.TO, "to1@xxx.com,to2@xxx.com");
-        result.setProperty(EmailPropertiesConstants.CC, "cc@xxx.com");
-        result.setProperty(EmailPropertiesConstants.BCC, "bcc@xxx.com");
-        result.setProperty(EmailPropertiesConstants.IS_DEBUG, Boolean.FALSE.toString());
-        return result;
+    private EmailConfiguration createEmailConfiguration() {
+        return new EmailConfiguration("xxx", 465, "xxx", "xxx", true, "Unit test notification", "from@xxx.com", "to1@xxx.com,to2@xxx.com", "cc@xxx.com", "bcc@xxx.com", false);
     }
 }
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/IgnoreJobErrorHandler.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/IgnoreJobErrorHandler.java
index 6e8ad3d..90ac5bc 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/IgnoreJobErrorHandler.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/IgnoreJobErrorHandler.java
@@ -17,17 +17,16 @@
 
 package org.apache.shardingsphere.elasticjob.error.handler.general;
 
+import org.apache.shardingsphere.elasticjob.error.handler.ErrorHandlerConfiguration;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandler;
 
-import java.util.Properties;
-
 /**
  * Job error handler for ignore exception.
  */
-public final class IgnoreJobErrorHandler implements JobErrorHandler {
+public final class IgnoreJobErrorHandler implements JobErrorHandler<ErrorHandlerConfiguration> {
     
     @Override
-    public void handleException(final String jobName, final Properties props, final Throwable cause) {
+    public void handleException(final String jobName, final ErrorHandlerConfiguration config, final Throwable cause) {
     }
     
     @Override
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/LogJobErrorHandler.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/LogJobErrorHandler.java
index 0e83df1..a939c6e 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/LogJobErrorHandler.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/LogJobErrorHandler.java
@@ -18,18 +18,17 @@
 package org.apache.shardingsphere.elasticjob.error.handler.general;
 
 import lombok.extern.slf4j.Slf4j;
+import org.apache.shardingsphere.elasticjob.error.handler.ErrorHandlerConfiguration;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandler;
 
-import java.util.Properties;
-
 /**
  * Job error handler for log error message.
  */
 @Slf4j
-public final class LogJobErrorHandler implements JobErrorHandler {
+public final class LogJobErrorHandler implements JobErrorHandler<ErrorHandlerConfiguration> {
     
     @Override
-    public void handleException(final String jobName, final Properties props, final Throwable cause) {
+    public void handleException(final String jobName, final ErrorHandlerConfiguration config, final Throwable cause) {
         log.error(String.format("Job '%s' exception occur in job processing", jobName), cause);
     }
     
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/ThrowJobErrorHandler.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/ThrowJobErrorHandler.java
index f9f9e3e..3bd4a21 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/ThrowJobErrorHandler.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/general/ThrowJobErrorHandler.java
@@ -17,18 +17,17 @@
 
 package org.apache.shardingsphere.elasticjob.error.handler.general;
 
+import org.apache.shardingsphere.elasticjob.error.handler.ErrorHandlerConfiguration;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandler;
 import org.apache.shardingsphere.elasticjob.infra.exception.JobSystemException;
 
-import java.util.Properties;
-
 /**
  * Job error handler for throw exception.
  */
-public final class ThrowJobErrorHandler implements JobErrorHandler {
+public final class ThrowJobErrorHandler implements JobErrorHandler<ErrorHandlerConfiguration> {
     
     @Override
-    public void handleException(final String jobName, final Properties props, final Throwable cause) {
+    public void handleException(final String jobName, final ErrorHandlerConfiguration config, final Throwable cause) {
         throw new JobSystemException(cause);
     }
     
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/IgnoreJobErrorHandlerTest.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/IgnoreJobErrorHandlerTest.java
index d160a37..a820302 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/IgnoreJobErrorHandlerTest.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/IgnoreJobErrorHandlerTest.java
@@ -21,13 +21,12 @@ import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandlerFactory
 import org.apache.shardingsphere.elasticjob.infra.exception.JobConfigurationException;
 import org.junit.Test;
 
-import java.util.Properties;
-
 public final class IgnoreJobErrorHandlerTest {
     
+    @SuppressWarnings("unchecked")
     @Test
     public void assertHandleException() {
-        JobErrorHandlerFactory.createHandler("IGNORE").orElseThrow(() -> new JobConfigurationException("IGNORE error handler not found."))
-                .handleException("test_job", new Properties(), new RuntimeException("test"));
+        JobErrorHandlerFactory.createHandler("IGNORE").orElseThrow(
+            () -> new JobConfigurationException("IGNORE error handler not found.")).handleException("test_job", null, new RuntimeException("test"));
     }
 }
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/LogJobErrorHandlerTest.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/LogJobErrorHandlerTest.java
index 18fe5ce..b7d7e24 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/LogJobErrorHandlerTest.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/LogJobErrorHandlerTest.java
@@ -28,7 +28,6 @@ import org.slf4j.Logger;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.Properties;
 
 import static org.mockito.Mockito.verify;
 
@@ -43,7 +42,7 @@ public final class LogJobErrorHandlerTest {
         LogJobErrorHandler actual = (LogJobErrorHandler) JobErrorHandlerFactory.createHandler("LOG").orElseThrow(() -> new JobConfigurationException("LOG error handler not found."));
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", new Properties(), cause);
+        actual.handleException("test_job", null, cause);
         verify(log).error("Job 'test_job' exception occur in job processing", cause);
     }
     
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/ThrowJobErrorHandlerTest.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/ThrowJobErrorHandlerTest.java
index 273a5e9..6efc5ae 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/ThrowJobErrorHandlerTest.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-general/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/general/ThrowJobErrorHandlerTest.java
@@ -22,13 +22,12 @@ import org.apache.shardingsphere.elasticjob.infra.exception.JobConfigurationExce
 import org.apache.shardingsphere.elasticjob.infra.exception.JobSystemException;
 import org.junit.Test;
 
-import java.util.Properties;
-
 public final class ThrowJobErrorHandlerTest {
     
+    @SuppressWarnings("unchecked")
     @Test(expected = JobSystemException.class)
     public void assertHandleException() {
-        JobErrorHandlerFactory.createHandler("THROW").orElseThrow(() -> new JobConfigurationException("THROW error handler not found."))
-                .handleException("test_job", new Properties(), new RuntimeException("test"));
+        JobErrorHandlerFactory.createHandler("THROW").orElseThrow(
+            () -> new JobConfigurationException("THROW error handler not found.")).handleException("test_job", null, new RuntimeException("test"));
     }
 }
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/config/WechatPropertiesConstants.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatConfiguration.java
similarity index 59%
rename from elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/config/WechatPropertiesConstants.java
rename to elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatConfiguration.java
index 4825705..f6e844e 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/config/WechatPropertiesConstants.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatConfiguration.java
@@ -15,22 +15,22 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.elasticjob.error.handler.wechat.config;
+package org.apache.shardingsphere.elasticjob.error.handler.wechat;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.elasticjob.error.handler.ErrorHandlerConfiguration;
 
 /**
- * Job error handler properties constants for send error message via wechat.
+ * Job error handler configuration for send error message via wechat.
  */
-public final class WechatPropertiesConstants {
-    
-    public static final String DEFAULT_CONNECT_TIMEOUT_MILLISECOND = "3000";
-    
-    public static final String DEFAULT_READ_TIMEOUT_MILLISECOND = "5000";
-    
-    private static final String PREFIX = "wechat.";
+@RequiredArgsConstructor
+@Getter
+public final class WechatConfiguration implements ErrorHandlerConfiguration {
     
-    public static final String WEBHOOK = PREFIX + "webhook";
+    private final String webhook;
     
-    public static final String CONNECT_TIMEOUT_MILLISECOND = PREFIX + "connectTimeoutMillisecond";
+    private final int connectTimeoutMillisecond;
     
-    public static final String READ_TIMEOUT_MILLISECOND = PREFIX + "readTimeoutMillisecond";
+    private final int readTimeoutMillisecond;
 }
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatJobErrorHandler.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatJobErrorHandler.java
index 73c62c2..e92f2d8 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatJobErrorHandler.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatJobErrorHandler.java
@@ -29,7 +29,6 @@ import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.util.EntityUtils;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandler;
-import org.apache.shardingsphere.elasticjob.error.handler.wechat.config.WechatConfiguration;
 import org.apache.shardingsphere.elasticjob.infra.json.GsonFactory;
 
 import java.io.IOException;
@@ -38,13 +37,12 @@ import java.io.StringWriter;
 import java.net.HttpURLConnection;
 import java.nio.charset.StandardCharsets;
 import java.util.Collections;
-import java.util.Properties;
 
 /**
  * Job error handler for send error message via wechat.
  */
 @Slf4j
-public final class WechatJobErrorHandler implements JobErrorHandler {
+public final class WechatJobErrorHandler implements JobErrorHandler<WechatConfiguration> {
     
     private final CloseableHttpClient httpclient = HttpClients.createDefault();
     
@@ -65,8 +63,7 @@ public final class WechatJobErrorHandler implements JobErrorHandler {
     }
     
     @Override
-    public void handleException(final String jobName, final Properties props, final Throwable cause) {
-        WechatConfiguration config = new WechatConfiguration(props);
+    public void handleException(final String jobName, final WechatConfiguration config, final Throwable cause) {
         HttpPost httpPost = createHTTPPostMethod(jobName, cause, config);
         try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
             int status = response.getStatusLine().getStatusCode();
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/config/WechatConfiguration.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/config/WechatConfiguration.java
deleted file mode 100644
index e36103f..0000000
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/main/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/config/WechatConfiguration.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *  
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.error.handler.wechat.config;
-
-import lombok.Getter;
-
-import java.util.Properties;
-
-/**
- * Job error handler configuration for send error message via wechat.
- */
-@Getter
-public final class WechatConfiguration {
-    
-    private final String webhook;
-    
-    private final Integer connectTimeoutMillisecond;
-    
-    private final Integer readTimeoutMillisecond;
-    
-    public WechatConfiguration(final Properties props) {
-        webhook = props.getProperty(WechatPropertiesConstants.WEBHOOK);
-        connectTimeoutMillisecond = Integer.parseInt(props.getProperty(WechatPropertiesConstants.CONNECT_TIMEOUT_MILLISECOND, WechatPropertiesConstants.DEFAULT_CONNECT_TIMEOUT_MILLISECOND));
-        readTimeoutMillisecond = Integer.parseInt(props.getProperty(WechatPropertiesConstants.READ_TIMEOUT_MILLISECOND, WechatPropertiesConstants.DEFAULT_READ_TIMEOUT_MILLISECOND));
-    }
-}
diff --git a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatJobErrorHandlerTest.java b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatJobErrorHandlerTest.java
index 3b071fc..b58c00d 100644
--- a/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatJobErrorHandlerTest.java
+++ b/elasticjob-error-handler/elasticjob-error-handler-type/elasticjob-error-handler-wechat/src/test/java/org/apache/shardingsphere/elasticjob/error/handler/wechat/WechatJobErrorHandlerTest.java
@@ -19,7 +19,6 @@ package org.apache.shardingsphere.elasticjob.error.handler.wechat;
 
 import lombok.SneakyThrows;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandlerFactory;
-import org.apache.shardingsphere.elasticjob.error.handler.wechat.config.WechatPropertiesConstants;
 import org.apache.shardingsphere.elasticjob.error.handler.wechat.fixture.WechatInternalController;
 import org.apache.shardingsphere.elasticjob.infra.exception.JobConfigurationException;
 import org.apache.shardingsphere.elasticjob.restful.NettyRestfulService;
@@ -35,7 +34,6 @@ import org.slf4j.Logger;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.Properties;
 
 import static org.mockito.Mockito.verify;
 
@@ -72,7 +70,7 @@ public final class WechatJobErrorHandlerTest {
         WechatJobErrorHandler actual = getWechatJobErrorHandler();
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", getJobProperties("http://localhost:9872/send?key=mocked_key"), cause);
+        actual.handleException("test_job", new WechatConfiguration("http://localhost:9872/send?key=mocked_key", 1000, 2000), cause);
         verify(log).info("An exception has occurred in Job '{}', Notification to wechat was successful.", "test_job", cause);
     }
     
@@ -81,7 +79,7 @@ public final class WechatJobErrorHandlerTest {
         WechatJobErrorHandler actual = getWechatJobErrorHandler();
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", getJobProperties("http://localhost:9872/send?key=wrong_key"), cause);
+        actual.handleException("test_job", new WechatConfiguration("http://localhost:9872/send?key=wrong_key", 1000, 2000), cause);
         verify(log).info("An exception has occurred in Job '{}', But failed to send alert by wechat because of: {}", "test_job", "token is invalid", cause);
     }
     
@@ -90,7 +88,7 @@ public final class WechatJobErrorHandlerTest {
         WechatJobErrorHandler actual = getWechatJobErrorHandler();
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", getJobProperties("http://wrongUrl"), cause);
+        actual.handleException("test_job", new WechatConfiguration("http://wrongUrl", 1000, 2000), cause);
         verify(log).error("An exception has occurred in Job '{}', But failed to send alert by wechat because of", "test_job", cause);
     }
     
@@ -99,7 +97,7 @@ public final class WechatJobErrorHandlerTest {
         WechatJobErrorHandler actual = getWechatJobErrorHandler();
         setStaticFieldValue(actual);
         Throwable cause = new RuntimeException("test");
-        actual.handleException("test_job", getJobProperties("http://localhost:9872/404"), cause);
+        actual.handleException("test_job", new WechatConfiguration("http://localhost:9872/404", 1000, 2000), cause);
         verify(log).error("An exception has occurred in Job '{}', But failed to send alert by wechat because of: Unexpected response status: {}", "test_job", 404, cause);
     }
 
@@ -116,12 +114,4 @@ public final class WechatJobErrorHandlerTest {
         modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
         field.set(wechatJobErrorHandler, log);
     }
-    
-    private Properties getJobProperties(final String webhook) {
-        Properties result = new Properties();
-        result.setProperty(WechatPropertiesConstants.WEBHOOK, webhook);
-        result.setProperty(WechatPropertiesConstants.CONNECT_TIMEOUT_MILLISECOND, "1000");
-        result.setProperty(WechatPropertiesConstants.READ_TIMEOUT_MILLISECOND, "2000");
-        return result;
-    }
 }
diff --git a/elasticjob-executor/elasticjob-executor-kernel/src/main/java/org/apache/shardingsphere/elasticjob/executor/ElasticJobExecutor.java b/elasticjob-executor/elasticjob-executor-kernel/src/main/java/org/apache/shardingsphere/elasticjob/executor/ElasticJobExecutor.java
index c828434..54c6e83 100644
--- a/elasticjob-executor/elasticjob-executor-kernel/src/main/java/org/apache/shardingsphere/elasticjob/executor/ElasticJobExecutor.java
+++ b/elasticjob-executor/elasticjob-executor-kernel/src/main/java/org/apache/shardingsphere/elasticjob/executor/ElasticJobExecutor.java
@@ -20,15 +20,16 @@ package org.apache.shardingsphere.elasticjob.executor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.shardingsphere.elasticjob.api.ElasticJob;
 import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
+import org.apache.shardingsphere.elasticjob.error.handler.ErrorHandlerConfiguration;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandler;
 import org.apache.shardingsphere.elasticjob.error.handler.JobErrorHandlerFactory;
+import org.apache.shardingsphere.elasticjob.executor.item.JobItemExecutor;
+import org.apache.shardingsphere.elasticjob.executor.item.JobItemExecutorFactory;
 import org.apache.shardingsphere.elasticjob.infra.env.IpUtils;
 import org.apache.shardingsphere.elasticjob.infra.exception.ExceptionUtils;
 import org.apache.shardingsphere.elasticjob.infra.exception.JobConfigurationException;
 import org.apache.shardingsphere.elasticjob.infra.exception.JobExecutionEnvironmentException;
 import org.apache.shardingsphere.elasticjob.infra.handler.threadpool.JobExecutorServiceHandlerFactory;
-import org.apache.shardingsphere.elasticjob.executor.item.JobItemExecutor;
-import org.apache.shardingsphere.elasticjob.executor.item.JobItemExecutorFactory;
 import org.apache.shardingsphere.elasticjob.infra.listener.ShardingContexts;
 import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
 import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent.ExecutionSource;
@@ -36,6 +37,7 @@ import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent.St
 
 import java.util.Collection;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
@@ -86,7 +88,7 @@ public final class ElasticJobExecutor {
         try {
             jobFacade.checkJobExecutionEnvironment();
         } catch (final JobExecutionEnvironmentException cause) {
-            jobErrorHandler.handleException(jobConfig.getJobName(), jobConfig.getProps(), cause);
+            jobErrorHandler.handleException(jobConfig.getJobName(), findErrorHandlerConfiguration().orElse(null), cause);
         }
         ShardingContexts shardingContexts = jobFacade.getShardingContexts();
         jobFacade.postJobStatusTraceEvent(shardingContexts.getTaskId(), State.TASK_STAGING, String.format("Job '%s' execute begin.", jobConfig.getJobName()));
@@ -101,7 +103,7 @@ public final class ElasticJobExecutor {
             //CHECKSTYLE:OFF
         } catch (final Throwable cause) {
             //CHECKSTYLE:ON
-            jobErrorHandler.handleException(jobConfig.getJobName(), jobConfig.getProps(), cause);
+            jobErrorHandler.handleException(jobConfig.getJobName(), findErrorHandlerConfiguration().orElse(null), cause);
         }
         execute(shardingContexts, ExecutionSource.NORMAL_TRIGGER);
         while (jobFacade.isExecuteMisfired(shardingContexts.getShardingItemParameters().keySet())) {
@@ -114,7 +116,7 @@ public final class ElasticJobExecutor {
             //CHECKSTYLE:OFF
         } catch (final Throwable cause) {
             //CHECKSTYLE:ON
-            jobErrorHandler.handleException(jobConfig.getJobName(), jobConfig.getProps(), cause);
+            jobErrorHandler.handleException(jobConfig.getJobName(), findErrorHandlerConfiguration().orElse(null), cause);
         }
     }
     
@@ -184,10 +186,14 @@ public final class ElasticJobExecutor {
             completeEvent = startEvent.executionFailure(ExceptionUtils.transform(cause));
             jobFacade.postJobExecutionEvent(completeEvent);
             itemErrorMessages.put(item, ExceptionUtils.transform(cause));
-            jobErrorHandler.handleException(jobConfig.getJobName(), jobConfig.getProps(), cause);
+            jobErrorHandler.handleException(jobConfig.getJobName(), findErrorHandlerConfiguration().orElse(null), cause);
         }
     }
     
+    private Optional<ErrorHandlerConfiguration> findErrorHandlerConfiguration() {
+        return jobConfig.getExtraConfigurations().stream().filter(each -> each instanceof ErrorHandlerConfiguration).map(extraConfig -> (ErrorHandlerConfiguration) extraConfig).findFirst();
+    }
+    
     /**
      * Shutdown executor.
      */
diff --git a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/OneOffJobBootstrap.java b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/OneOffJobBootstrap.java
index 32f8a2d..9f7ab57 100644
--- a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/OneOffJobBootstrap.java
+++ b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/OneOffJobBootstrap.java
@@ -19,14 +19,13 @@ package org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
-import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.JobBootstrap;
 import org.apache.shardingsphere.elasticjob.api.ElasticJob;
 import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
+import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.JobBootstrap;
 import org.apache.shardingsphere.elasticjob.lite.internal.instance.InstanceOperation;
+import org.apache.shardingsphere.elasticjob.lite.internal.schedule.JobScheduler;
 import org.apache.shardingsphere.elasticjob.lite.internal.storage.JobNodePath;
 import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
-import org.apache.shardingsphere.elasticjob.lite.internal.schedule.JobScheduler;
-import org.apache.shardingsphere.elasticjob.tracing.api.TracingConfiguration;
 
 /**
  * One off job bootstrap.
@@ -39,18 +38,10 @@ public final class OneOffJobBootstrap implements JobBootstrap {
         jobScheduler = new JobScheduler(regCenter, elasticJob, jobConfig);
     }
     
-    public OneOffJobBootstrap(final CoordinatorRegistryCenter regCenter, final ElasticJob elasticJob, final JobConfiguration jobConfig, final TracingConfiguration tracingConfig) {
-        jobScheduler = new JobScheduler(regCenter, elasticJob, jobConfig, tracingConfig);
-    }
-    
     public OneOffJobBootstrap(final CoordinatorRegistryCenter regCenter, final String elasticJobType, final JobConfiguration jobConfig) {
         jobScheduler = new JobScheduler(regCenter, elasticJobType, jobConfig);
     }
     
-    public OneOffJobBootstrap(final CoordinatorRegistryCenter regCenter, final String elasticJobType, final JobConfiguration jobConfig, final TracingConfiguration tracingConfig) {
-        jobScheduler = new JobScheduler(regCenter, elasticJobType, jobConfig, tracingConfig);
-    }
-    
     /**
      * Execute job.
      */
diff --git a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/ScheduleJobBootstrap.java b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/ScheduleJobBootstrap.java
index 513d67f..2dba62b 100644
--- a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/ScheduleJobBootstrap.java
+++ b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/api/bootstrap/impl/ScheduleJobBootstrap.java
@@ -19,12 +19,11 @@ package org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl;
 
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
-import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.JobBootstrap;
 import org.apache.shardingsphere.elasticjob.api.ElasticJob;
 import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
-import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
+import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.JobBootstrap;
 import org.apache.shardingsphere.elasticjob.lite.internal.schedule.JobScheduler;
-import org.apache.shardingsphere.elasticjob.tracing.api.TracingConfiguration;
+import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
 
 /**
  * Schedule job bootstrap.
@@ -37,18 +36,10 @@ public final class ScheduleJobBootstrap implements JobBootstrap {
         jobScheduler = new JobScheduler(regCenter, elasticJob, jobConfig);
     }
     
-    public ScheduleJobBootstrap(final CoordinatorRegistryCenter regCenter, final ElasticJob elasticJob, final JobConfiguration jobConfig, final TracingConfiguration tracingConfig) {
-        jobScheduler = new JobScheduler(regCenter, elasticJob, jobConfig, tracingConfig);
-    }
-    
     public ScheduleJobBootstrap(final CoordinatorRegistryCenter regCenter, final String elasticJobType, final JobConfiguration jobConfig) {
         jobScheduler = new JobScheduler(regCenter, elasticJobType, jobConfig);
     }
     
-    public ScheduleJobBootstrap(final CoordinatorRegistryCenter regCenter, final String elasticJobType, final JobConfiguration jobConfig, final TracingConfiguration tracingConfig) {
-        jobScheduler = new JobScheduler(regCenter, elasticJobType, jobConfig, tracingConfig);
-    }
-    
     /**
      * Schedule job.
      */
diff --git a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduler.java b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduler.java
index 24a371d..9b5b3af 100644
--- a/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduler.java
+++ b/elasticjob-lite/elasticjob-lite-core/src/main/java/org/apache/shardingsphere/elasticjob/lite/internal/schedule/JobScheduler.java
@@ -39,6 +39,7 @@ import org.quartz.impl.StdSchedulerFactory;
 import org.quartz.simpl.SimpleThreadPool;
 
 import java.util.Collection;
+import java.util.Optional;
 import java.util.Properties;
 import java.util.stream.Collectors;
 
@@ -69,10 +70,6 @@ public final class JobScheduler {
     private final JobScheduleController jobScheduleController;
     
     public JobScheduler(final CoordinatorRegistryCenter regCenter, final ElasticJob elasticJob, final JobConfiguration jobConfig) {
-        this(regCenter, elasticJob, jobConfig, null);
-    }
-    
-    public JobScheduler(final CoordinatorRegistryCenter regCenter, final ElasticJob elasticJob, final JobConfiguration jobConfig, final TracingConfiguration<?> tracingConfig) {
         this.regCenter = regCenter;
         elasticJobType = null;
         final Collection<ElasticJobListener> elasticJobListeners = jobConfig.getJobListenerTypes().stream()
@@ -81,7 +78,7 @@ public final class JobScheduler {
                 .collect(Collectors.toList());
         setUpFacade = new SetUpFacade(regCenter, jobConfig.getJobName(), elasticJobListeners);
         schedulerFacade = new SchedulerFacade(regCenter, jobConfig.getJobName());
-        jobFacade = new LiteJobFacade(regCenter, jobConfig.getJobName(), elasticJobListeners, tracingConfig);
+        jobFacade = new LiteJobFacade(regCenter, jobConfig.getJobName(), elasticJobListeners, findTracingConfiguration(jobConfig).orElse(null));
         jobExecutor = null == elasticJob ? new ElasticJobExecutor(elasticJobType, jobConfig, jobFacade) : new ElasticJobExecutor(elasticJob, jobConfig, jobFacade);
         String jobClassName = JobClassNameProviderFactory.getProvider().getJobClassName(elasticJob);
         this.jobConfig = setUpFacade.setUpJobConfiguration(jobClassName, jobConfig);
@@ -108,6 +105,10 @@ public final class JobScheduler {
         jobScheduleController = createJobScheduleController();
     }
     
+    private Optional<TracingConfiguration> findTracingConfiguration(final JobConfiguration jobConfig) {
+        return jobConfig.getExtraConfigurations().stream().filter(each -> each instanceof TracingConfiguration).findFirst().map(extraConfig -> (TracingConfiguration) extraConfig);
+    }
+    
     private void setGuaranteeServiceForElasticJobListeners(final CoordinatorRegistryCenter regCenter, final Collection<ElasticJobListener> elasticJobListeners) {
         GuaranteeService guaranteeService = new GuaranteeService(regCenter, jobConfig.getJobName());
         for (ElasticJobListener each : elasticJobListeners) {
diff --git a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-boot-starter/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/boot/job/ElasticJobLiteAutoConfiguration.java b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-boot-starter/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/boot/job/ElasticJobLiteAutoConfiguration.java
index 7db0f90..b4a94c9 100644
--- a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-boot-starter/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/boot/job/ElasticJobLiteAutoConfiguration.java
+++ b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-boot-starter/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/boot/job/ElasticJobLiteAutoConfiguration.java
@@ -102,31 +102,43 @@ public class ElasticJobLiteAutoConfiguration implements ApplicationContextAware
     }
     
     private void registerClassedJob(final String jobName, final String jobBootstrapBeanName, final SingletonBeanRegistry singletonBeanRegistry, final CoordinatorRegistryCenter registryCenter,
-                                    final TracingConfiguration tracingConfiguration, final ElasticJobConfigurationProperties jobConfigurationProperties) {
-        JobConfiguration jobConfiguration = jobConfigurationProperties.toJobConfiguration(jobName);
+                                    final TracingConfiguration tracingConfig, final ElasticJobConfigurationProperties jobConfigurationProperties) {
+        JobConfiguration jobConfig = jobConfigurationProperties.toJobConfiguration(jobName);
         ElasticJob elasticJob = applicationContext.getBean(jobConfigurationProperties.getElasticJobClass());
-        if (Strings.isNullOrEmpty(jobConfiguration.getCron())) {
+        if (Strings.isNullOrEmpty(jobConfig.getCron())) {
             Preconditions.checkArgument(!Strings.isNullOrEmpty(jobBootstrapBeanName), "The property [jobBootstrapBeanName] is required for one off job.");
+            if (null != tracingConfig) {
+                jobConfig.getExtraConfigurations().add(tracingConfig);
+            }
             singletonBeanRegistry.registerSingleton(jobBootstrapBeanName,
-                    new OneOffJobBootstrap(registryCenter, elasticJob, jobConfiguration, tracingConfiguration));
+                    new OneOffJobBootstrap(registryCenter, elasticJob, jobConfig));
         } else {
-            String beanName = !Strings.isNullOrEmpty(jobBootstrapBeanName) ? jobBootstrapBeanName : jobConfiguration.getJobName() + "ScheduleJobBootstrap";
+            String beanName = !Strings.isNullOrEmpty(jobBootstrapBeanName) ? jobBootstrapBeanName : jobConfig.getJobName() + "ScheduleJobBootstrap";
+            if (null != tracingConfig) {
+                jobConfig.getExtraConfigurations().add(tracingConfig);
+            }
             singletonBeanRegistry.registerSingleton(beanName,
-                    new ScheduleJobBootstrap(registryCenter, elasticJob, jobConfiguration, tracingConfiguration));
+                    new ScheduleJobBootstrap(registryCenter, elasticJob, jobConfig));
         }
     }
     
     private void registerTypedJob(final String jobName, final String jobBootstrapBeanName, final SingletonBeanRegistry singletonBeanRegistry, final CoordinatorRegistryCenter registryCenter,
-                                  final TracingConfiguration tracingConfiguration, final ElasticJobConfigurationProperties jobConfigurationProperties) {
-        JobConfiguration jobConfiguration = jobConfigurationProperties.toJobConfiguration(jobName);
-        if (Strings.isNullOrEmpty(jobConfiguration.getCron())) {
+                                  final TracingConfiguration tracingConfig, final ElasticJobConfigurationProperties jobConfigurationProperties) {
+        JobConfiguration jobConfig = jobConfigurationProperties.toJobConfiguration(jobName);
+        if (Strings.isNullOrEmpty(jobConfig.getCron())) {
             Preconditions.checkArgument(!Strings.isNullOrEmpty(jobBootstrapBeanName), "The property [jobBootstrapBeanName] is required for one off job.");
+            if (null != tracingConfig) {
+                jobConfig.getExtraConfigurations().add(tracingConfig);
+            }
             singletonBeanRegistry.registerSingleton(jobBootstrapBeanName,
-                    new OneOffJobBootstrap(registryCenter, jobConfigurationProperties.getElasticJobType(), jobConfiguration, tracingConfiguration));
+                    new OneOffJobBootstrap(registryCenter, jobConfigurationProperties.getElasticJobType(), jobConfig));
         } else {
-            String beanName = !Strings.isNullOrEmpty(jobBootstrapBeanName) ? jobBootstrapBeanName : jobConfiguration.getJobName() + "ScheduleJobBootstrap";
+            String beanName = !Strings.isNullOrEmpty(jobBootstrapBeanName) ? jobBootstrapBeanName : jobConfig.getJobName() + "ScheduleJobBootstrap";
+            if (null != tracingConfig) {
+                jobConfig.getExtraConfigurations().add(tracingConfig);
+            }
             singletonBeanRegistry.registerSingleton(beanName,
-                    new ScheduleJobBootstrap(registryCenter, jobConfigurationProperties.getElasticJobType(), jobConfiguration, tracingConfiguration));
+                    new ScheduleJobBootstrap(registryCenter, jobConfigurationProperties.getElasticJobType(), jobConfig));
         }
     }
 }
diff --git a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/parser/JobBeanDefinitionParser.java b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/parser/JobBeanDefinitionParser.java
index 5360e20..b198edb 100644
--- a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/parser/JobBeanDefinitionParser.java
+++ b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/parser/JobBeanDefinitionParser.java
@@ -18,11 +18,10 @@
 package org.apache.shardingsphere.elasticjob.lite.spring.namespace.job.parser;
 
 import com.google.common.base.Strings;
+import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
 import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl.OneOffJobBootstrap;
 import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl.ScheduleJobBootstrap;
-import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
 import org.apache.shardingsphere.elasticjob.lite.spring.namespace.job.tag.JobBeanDefinitionTag;
-import org.apache.shardingsphere.elasticjob.lite.spring.namespace.job.tag.JobListenerBeanDefinitionTag;
 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -34,8 +33,8 @@ import org.springframework.util.xml.DomUtils;
 import org.w3c.dom.Element;
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
-import java.util.List;
 import java.util.Properties;
 
 /**
@@ -60,10 +59,6 @@ public final class JobBeanDefinitionParser extends AbstractBeanDefinitionParser
             factory.addConstructorArgReference(element.getAttribute(JobBeanDefinitionTag.JOB_REF_ATTRIBUTE));
         }
         factory.addConstructorArgValue(createJobConfigurationBeanDefinition(element, parserContext));
-        String tracingRef = element.getAttribute(JobBeanDefinitionTag.TRACING_REF_ATTRIBUTE);
-        if (!Strings.isNullOrEmpty(tracingRef)) {
-            factory.addConstructorArgReference(tracingRef);
-        }
         return factory.getBeanDefinition();
     }
     
@@ -87,6 +82,14 @@ public final class JobBeanDefinitionParser extends AbstractBeanDefinitionParser
         } else {
             result.addConstructorArgValue(Arrays.asList(element.getAttribute(JobBeanDefinitionTag.JOB_LISTENER_TYPES_ATTRIBUTE).split(",")));
         }
+        String tracingRef = element.getAttribute(JobBeanDefinitionTag.TRACING_REF_ATTRIBUTE);
+        if (Strings.isNullOrEmpty(tracingRef)) {
+            result.addConstructorArgValue(Collections.emptyList());
+        } else {
+            Collection<BeanDefinition> extraConfigs = new ManagedList<>(1);
+            extraConfigs.add(parserContext.getRegistry().getBeanDefinition(tracingRef));
+            result.addConstructorArgValue(extraConfigs);
+        }
         result.addConstructorArgValue(element.getAttribute(JobBeanDefinitionTag.DESCRIPTION_ATTRIBUTE));
         result.addConstructorArgValue(parsePropsElement(element, parserContext));
         result.addConstructorArgValue(element.getAttribute(JobBeanDefinitionTag.DISABLED_ATTRIBUTE));
@@ -98,23 +101,4 @@ public final class JobBeanDefinitionParser extends AbstractBeanDefinitionParser
         Element propsElement = DomUtils.getChildElementByTagName(element, JobBeanDefinitionTag.PROPS_TAG);
         return null == propsElement ? new Properties() : parserContext.getDelegate().parsePropsElement(propsElement);
     }
-    
-    private List<BeanDefinition> createJobListeners(final Element element) {
-        Element listenerElement = DomUtils.getChildElementByTagName(element, JobListenerBeanDefinitionTag.LISTENER_TAG);
-        Element distributedListenerElement = DomUtils.getChildElementByTagName(element, JobListenerBeanDefinitionTag.DISTRIBUTED_LISTENER_TAG);
-        List<BeanDefinition> result = new ManagedList<>(2);
-        if (null != listenerElement) {
-            BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(listenerElement.getAttribute(JobListenerBeanDefinitionTag.CLASS_ATTRIBUTE));
-            factory.setScope(BeanDefinition.SCOPE_PROTOTYPE);
-            result.add(factory.getBeanDefinition());
-        }
-        if (null != distributedListenerElement) {
-            BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(distributedListenerElement.getAttribute(JobListenerBeanDefinitionTag.CLASS_ATTRIBUTE));
-            factory.setScope(BeanDefinition.SCOPE_PROTOTYPE);
-            factory.addConstructorArgValue(distributedListenerElement.getAttribute(JobListenerBeanDefinitionTag.DISTRIBUTED_LISTENER_STARTED_TIMEOUT_MILLISECONDS_ATTRIBUTE));
-            factory.addConstructorArgValue(distributedListenerElement.getAttribute(JobListenerBeanDefinitionTag.DISTRIBUTED_LISTENER_COMPLETED_TIMEOUT_MILLISECONDS_ATTRIBUTE));
-            result.add(factory.getBeanDefinition());
-        }
-        return result;
-    }
 }
diff --git a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/tag/JobBeanDefinitionTag.java b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/tag/JobBeanDefinitionTag.java
index 6001029..2bd207d 100644
--- a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/tag/JobBeanDefinitionTag.java
+++ b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/main/java/org/apache/shardingsphere/elasticjob/lite/spring/namespace/job/tag/JobBeanDefinitionTag.java
@@ -59,6 +59,8 @@ public final class JobBeanDefinitionTag {
     public static final String JOB_ERROR_HANDLER_TYPE_ATTRIBUTE = "job-error-handler-type";
     
     public static final String JOB_LISTENER_TYPES_ATTRIBUTE = "job-listener-types";
+
+    public static final String EXTRA_CONFIGURATION_REF_ATTRIBUTE = "extra-configurations-ref";
     
     public static final String DESCRIPTION_ATTRIBUTE = "description";
     
diff --git a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/test/resources/META-INF/job/withEventTraceRdb.xml b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/test/resources/META-INF/job/withEventTraceRdb.xml
index 89451bd..dad9611 100644
--- a/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/test/resources/META-INF/job/withEventTraceRdb.xml
+++ b/elasticjob-lite/elasticjob-lite-spring/elasticjob-lite-spring-namespace/src/test/resources/META-INF/job/withEventTraceRdb.xml
@@ -31,7 +31,8 @@
     
     <elasticjob:job id="simpleElasticJob_namespace_event_trace_rdb" job-ref="fooJob" registry-center-ref="regCenter" tracing-ref="elasticJobTrace" 
              cron="${simpleJob.cron}" sharding-total-count="${simpleJob.shardingTotalCount}" sharding-item-parameters="${simpleJob.shardingItemParameters}" job-executor-service-handler-type="SINGLE_THREAD" 
-             disabled="${simpleJob.disabled}" overwrite="${simpleJob.overwrite}" />
+             disabled="${simpleJob.disabled}" overwrite="${simpleJob.overwrite}">
+    </elasticjob:job>
     
     <elasticjob:job id="dataflowElasticJob_namespace_event_trace_rdb" job-ref="dataflowJob" registry-center-ref="regCenter" 
              cron="0/1 * * * * ?" sharding-total-count="3" sharding-item-parameters="0=A,1=B,2=C" job-error-handler-type="THROW" description="中文描述" overwrite="true" />
diff --git a/elasticjob-tracing/elasticjob-tracing-api/pom.xml b/elasticjob-tracing/elasticjob-tracing-api/pom.xml
index 397296f..a03e524 100644
--- a/elasticjob-tracing/elasticjob-tracing-api/pom.xml
+++ b/elasticjob-tracing/elasticjob-tracing-api/pom.xml
@@ -28,6 +28,12 @@
     
     <dependencies>
         <dependency>
+            <groupId>org.apache.shardingsphere.elasticjob</groupId>
+            <artifactId>elasticjob-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        
+        <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
diff --git a/elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java b/elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java
index c97bed6..e31c45b 100644
--- a/elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java
+++ b/elasticjob-tracing/elasticjob-tracing-api/src/main/java/org/apache/shardingsphere/elasticjob/tracing/api/TracingConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.elasticjob.tracing.api;
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.elasticjob.api.JobExtraConfiguration;
 
 /**
  * Tracing configuration.
@@ -27,7 +28,7 @@ import lombok.RequiredArgsConstructor;
  */
 @RequiredArgsConstructor
 @Getter
-public final class TracingConfiguration<T> {
+public final class TracingConfiguration<T> implements JobExtraConfiguration {
     
     private final String type;
     
diff --git a/examples/elasticjob-example-lite-java/src/main/java/org/apache/shardingsphere/elasticjob/lite/example/JavaMain.java b/examples/elasticjob-example-lite-java/src/main/java/org/apache/shardingsphere/elasticjob/lite/example/JavaMain.java
index c584911..76c183f 100644
--- a/examples/elasticjob-example-lite-java/src/main/java/org/apache/shardingsphere/elasticjob/lite/example/JavaMain.java
+++ b/examples/elasticjob-example-lite-java/src/main/java/org/apache/shardingsphere/elasticjob/lite/example/JavaMain.java
@@ -18,14 +18,14 @@
 package org.apache.shardingsphere.elasticjob.lite.example;
 
 import org.apache.commons.dbcp.BasicDataSource;
-import org.apache.shardingsphere.elasticjob.error.handler.dingtalk.config.DingtalkPropertiesConstants;
-import org.apache.shardingsphere.elasticjob.error.handler.email.config.EmailPropertiesConstants;
-import org.apache.shardingsphere.elasticjob.error.handler.wechat.config.WechatPropertiesConstants;
+import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
+import org.apache.shardingsphere.elasticjob.dataflow.props.DataflowJobProperties;
+import org.apache.shardingsphere.elasticjob.error.handler.dingtalk.DingtalkConfiguration;
+import org.apache.shardingsphere.elasticjob.error.handler.email.EmailConfiguration;
+import org.apache.shardingsphere.elasticjob.error.handler.wechat.WechatConfiguration;
 import org.apache.shardingsphere.elasticjob.http.props.HttpJobProperties;
 import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl.OneOffJobBootstrap;
 import org.apache.shardingsphere.elasticjob.lite.api.bootstrap.impl.ScheduleJobBootstrap;
-import org.apache.shardingsphere.elasticjob.api.JobConfiguration;
-import org.apache.shardingsphere.elasticjob.dataflow.props.DataflowJobProperties;
 import org.apache.shardingsphere.elasticjob.lite.example.job.dataflow.JavaDataflowJob;
 import org.apache.shardingsphere.elasticjob.lite.example.job.simple.JavaOccurErrorJob;
 import org.apache.shardingsphere.elasticjob.lite.example.job.simple.JavaSimpleJob;
@@ -98,78 +98,64 @@ public final class JavaMain {
         new ScheduleJobBootstrap(regCenter, "HTTP", JobConfiguration.newBuilder("javaHttpJob", 3)
                 .setProperty(HttpJobProperties.URI_KEY, "https://github.com")
                 .setProperty(HttpJobProperties.METHOD_KEY, "GET")
-                .cron("0/5 * * * * ?").shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").build(), tracingConfig).schedule();
+                .cron("0/5 * * * * ?").shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").addExtraConfigurations(tracingConfig).build()).schedule();
         
     }
     
     private static void setUpSimpleJob(final CoordinatorRegistryCenter regCenter, final TracingConfiguration<DataSource> tracingConfig) {
         new ScheduleJobBootstrap(regCenter, new JavaSimpleJob(), JobConfiguration.newBuilder("javaSimpleJob", 3)
-                .cron("0/5 * * * * ?").shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").build(), tracingConfig).schedule();
+                .cron("0/5 * * * * ?").shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").addExtraConfigurations(tracingConfig).build()).schedule();
     }
     
     private static void setUpDataflowJob(final CoordinatorRegistryCenter regCenter, final TracingConfiguration<DataSource> tracingConfig) {
         new ScheduleJobBootstrap(regCenter, new JavaDataflowJob(), JobConfiguration.newBuilder("javaDataflowElasticJob", 3)
                 .cron("0/5 * * * * ?").shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou")
-                .setProperty(DataflowJobProperties.STREAM_PROCESS_KEY, Boolean.TRUE.toString()).build(), tracingConfig).schedule();
+                .setProperty(DataflowJobProperties.STREAM_PROCESS_KEY, Boolean.TRUE.toString()).addExtraConfigurations(tracingConfig).build()).schedule();
     }
 
     private static void setUpOneOffJob(final CoordinatorRegistryCenter regCenter, final TracingConfiguration<DataSource> tracingConfig) {
         new OneOffJobBootstrap(regCenter, new JavaSimpleJob(), JobConfiguration.newBuilder("javaOneOffSimpleJob", 3)
-                .shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").build(), tracingConfig).execute();
+                .shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").addExtraConfigurations(tracingConfig).build()).execute();
     }
     
     private static void setUpScriptJob(final CoordinatorRegistryCenter regCenter, final TracingConfiguration<DataSource> tracingConfig) throws IOException {
         new ScheduleJobBootstrap(regCenter, "SCRIPT", JobConfiguration.newBuilder("scriptElasticJob", 3)
-                .cron("0/5 * * * * ?").setProperty(ScriptJobProperties.SCRIPT_KEY, buildScriptCommandLine()).build(), tracingConfig).schedule();
+                .cron("0/5 * * * * ?").setProperty(ScriptJobProperties.SCRIPT_KEY, buildScriptCommandLine()).addExtraConfigurations(tracingConfig).build()).schedule();
     }
     
     private static void setUpOneOffJobWithDingtalk(final CoordinatorRegistryCenter regCenter, final TracingConfiguration<DataSource> tracingConfig) {
         JobConfiguration jobConfig = JobConfiguration.newBuilder("javaOccurErrorOfDingtalkJob", 3)
-                .shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").jobErrorHandlerType("DINGTALK").build();
+                .shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").jobErrorHandlerType("DINGTALK").addExtraConfigurations(tracingConfig).build();
         setDingtalkConfiguration(jobConfig);
-        new OneOffJobBootstrap(regCenter, new JavaOccurErrorJob(), jobConfig, tracingConfig).execute();
+        new OneOffJobBootstrap(regCenter, new JavaOccurErrorJob(), jobConfig).execute();
     }
     
     private static void setUpOneOffJobWithWechat(final CoordinatorRegistryCenter regCenter, final TracingConfiguration<DataSource> tracingConfig) {
         JobConfiguration jobConfig = JobConfiguration.newBuilder("javaOccurErrorOfWechatJob", 3)
-                .shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").jobErrorHandlerType("WECHAT").build();
+                .shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").jobErrorHandlerType("WECHAT").addExtraConfigurations(tracingConfig).build();
         setWechatConfiguration(jobConfig);
-        new OneOffJobBootstrap(regCenter, new JavaOccurErrorJob(), jobConfig, tracingConfig).execute();
+        new OneOffJobBootstrap(regCenter, new JavaOccurErrorJob(), jobConfig).execute();
     }
     
     private static void setUpOneOffJobWithEmail(final CoordinatorRegistryCenter regCenter, final TracingConfiguration<DataSource> tracingConfig) {
         JobConfiguration jobConfig = JobConfiguration.newBuilder("javaOccurErrorOfEmailJob", 3)
-                .shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").jobErrorHandlerType("EMAIL").build();
+                .shardingItemParameters("0=Beijing,1=Shanghai,2=Guangzhou").jobErrorHandlerType("EMAIL").addExtraConfigurations(tracingConfig).build();
         setEmailConfiguration(jobConfig);
-        new OneOffJobBootstrap(regCenter, new JavaOccurErrorJob(), jobConfig, tracingConfig).execute();
+        new OneOffJobBootstrap(regCenter, new JavaOccurErrorJob(), jobConfig).execute();
     }
     
     private static void setDingtalkConfiguration(final JobConfiguration jobConfig) {
-        jobConfig.getProps().setProperty(DingtalkPropertiesConstants.WEBHOOK, "https://oapi.dingtalk.com/robot/send?access_token=42eead064e81ce81fc6af2c107fbe10a4339a3d40a7db8abf5b34d8261527a3f");
-        jobConfig.getProps().setProperty(DingtalkPropertiesConstants.KEYWORD, "keyword");
-        jobConfig.getProps().setProperty(DingtalkPropertiesConstants.SECRET, "SEC0b0a6b13b6823b95737dd83491c23adee5d8a7a649899a12217e038eddc84ff4");
-        jobConfig.getProps().setProperty(DingtalkPropertiesConstants.CONNECT_TIMEOUT_MILLISECOND, "7000");
-        jobConfig.getProps().setProperty(DingtalkPropertiesConstants.READ_TIMEOUT_MILLISECOND, "8000");
+        jobConfig.getExtraConfigurations().add(new DingtalkConfiguration("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=5308e20a-2900-484b-a332-b5bb701ade04", 
+                "keyword", "SEC0b0a6b13b6823b95737dd83491c23adee5d8a7a649899a12217e038eddc84ff4", 7000, 8000));
     }
     
     private static void setWechatConfiguration(final JobConfiguration jobConfig) {
-        jobConfig.getProps().setProperty(WechatPropertiesConstants.WEBHOOK, "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=5308e20a-2900-484b-a332-b5bb701ade04");
-        jobConfig.getProps().setProperty(WechatPropertiesConstants.CONNECT_TIMEOUT_MILLISECOND, "9000");
-        jobConfig.getProps().setProperty(WechatPropertiesConstants.READ_TIMEOUT_MILLISECOND, "5000");
+        jobConfig.getExtraConfigurations().add(new WechatConfiguration("https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=5308e20a-2900-484b-a332-b5bb701ade04", 9000, 5000));
     }
     
     private static void setEmailConfiguration(final JobConfiguration jobConfig) {
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.HOST, "host");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.PORT, "465");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.USERNAME, "username");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.PASSWORD, "password");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.IS_USE_SSL, "true");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.SUBJECT, "Test elasticJob error message");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.FROM, "from@xxx.com");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.TO, "to1@xxx.com,to2xxx.com");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.CC, "cc@xxx.com");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.BCC, "bcc@xxx.com");
-        jobConfig.getProps().setProperty(EmailPropertiesConstants.IS_DEBUG, "false");
+        jobConfig.getExtraConfigurations().add(new EmailConfiguration(
+                "host", 465, "username", "password", true, "Test elasticJob error message", "from@xxx.com", "to1@xxx.com,to2xxx.com", "cc@xxx.com", "bcc@xxx.com", false));
     }
     
     private static String buildScriptCommandLine() throws IOException {