You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2021/08/07 14:09:49 UTC

[shardingsphere] branch master updated: Refactor the spring namespace configuration. (#11681)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0f9511d  Refactor the spring namespace configuration. (#11681)
0f9511d is described below

commit 0f9511d070202eb41fd630ec069a81b6cff91db3
Author: gin <ja...@163.com>
AuthorDate: Sat Aug 7 22:09:24 2021 +0800

    Refactor the spring namespace configuration. (#11681)
    
    * Refactor the spring namespace configuration.
    
    * Remove unnecessary spaces.
---
 .../ShadowAlgorithmFactoryBean.java}               | 23 ++++---
 ...aceHandler.java => ShadowNamespaceHandler.java} | 10 ++-
 .../parser/ShadowRuleBeanDefinitionParser.java     | 72 +++++++++++++++++++--
 ....java => ShadowAlgorithmBeanDefinitionTag.java} | 12 +---
 ...erTag.java => ShadowRuleBeanDefinitionTag.java} | 21 +++++-
 .../main/resources/META-INF/namespace/shadow.xsd   | 49 ++++++++++++++
 .../src/main/resources/META-INF/spring.handlers    |  2 +-
 .../ShadowAlgorithmSpringNamespaceTest.java        | 75 ++++++++++++++++++++++
 .../namespace/ShadowSpringNamespaceTest.java       | 19 ++++--
 .../shadow-algorithm-application-context.xml       | 52 +++++++++++++++
 10 files changed, 300 insertions(+), 35 deletions(-)

diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/handler/ShadowRuleNamespaceHandler.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/factorybean/ShadowAlgorithmFactoryBean.java
similarity index 54%
copy from shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/handler/ShadowRuleNamespaceHandler.java
copy to shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/factorybean/ShadowAlgorithmFactoryBean.java
index f5aae3c..939aa88 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/handler/ShadowRuleNamespaceHandler.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/factorybean/ShadowAlgorithmFactoryBean.java
@@ -15,19 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.shadow.spring.namespace.handler;
+package org.apache.shardingsphere.shadow.spring.namespace.factorybean;
 
-import org.apache.shardingsphere.shadow.spring.namespace.parser.ShadowRuleBeanDefinitionParser;
-import org.apache.shardingsphere.shadow.spring.namespace.tag.ShadowDataSourceBeanDefinitionParserTag;
-import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader;
+import org.apache.shardingsphere.shadow.spi.ShadowAlgorithm;
+import org.apache.shardingsphere.spring.namespace.factorybean.ShardingSphereAlgorithmFactoryBean;
+
+import java.util.Properties;
 
 /**
- * Shadow rule namespace handler.
+ * Shadow algorithm factory bean.
  */
-public final class ShadowRuleNamespaceHandler extends NamespaceHandlerSupport {
+public final class ShadowAlgorithmFactoryBean extends ShardingSphereAlgorithmFactoryBean<ShadowAlgorithm> {
+    
+    static {
+        ShardingSphereServiceLoader.register(ShadowAlgorithm.class);
+    }
     
-    @Override
-    public void init() {
-        registerBeanDefinitionParser(ShadowDataSourceBeanDefinitionParserTag.ROOT_TAG, new ShadowRuleBeanDefinitionParser());
+    public ShadowAlgorithmFactoryBean(final String type, final Properties props) {
+        super(ShadowAlgorithm.class, type, props);
     }
 }
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/handler/ShadowRuleNamespaceHandler.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/handler/ShadowNamespaceHandler.java
similarity index 63%
rename from shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/handler/ShadowRuleNamespaceHandler.java
rename to shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/handler/ShadowNamespaceHandler.java
index f5aae3c..5c3ca5a 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/handler/ShadowRuleNamespaceHandler.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/handler/ShadowNamespaceHandler.java
@@ -17,17 +17,21 @@
 
 package org.apache.shardingsphere.shadow.spring.namespace.handler;
 
+import org.apache.shardingsphere.shadow.spring.namespace.factorybean.ShadowAlgorithmFactoryBean;
 import org.apache.shardingsphere.shadow.spring.namespace.parser.ShadowRuleBeanDefinitionParser;
-import org.apache.shardingsphere.shadow.spring.namespace.tag.ShadowDataSourceBeanDefinitionParserTag;
+import org.apache.shardingsphere.shadow.spring.namespace.tag.ShadowAlgorithmBeanDefinitionTag;
+import org.apache.shardingsphere.shadow.spring.namespace.tag.ShadowRuleBeanDefinitionTag;
+import org.apache.shardingsphere.spring.namespace.parser.ShardingSphereAlgorithmBeanDefinitionParser;
 import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
 
 /**
  * Shadow rule namespace handler.
  */
-public final class ShadowRuleNamespaceHandler extends NamespaceHandlerSupport {
+public final class ShadowNamespaceHandler extends NamespaceHandlerSupport {
     
     @Override
     public void init() {
-        registerBeanDefinitionParser(ShadowDataSourceBeanDefinitionParserTag.ROOT_TAG, new ShadowRuleBeanDefinitionParser());
+        registerBeanDefinitionParser(ShadowRuleBeanDefinitionTag.ROOT_TAG, new ShadowRuleBeanDefinitionParser());
+        registerBeanDefinitionParser(ShadowAlgorithmBeanDefinitionTag.ROOT_TAG, new ShardingSphereAlgorithmBeanDefinitionParser(ShadowAlgorithmFactoryBean.class));
     }
 }
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/parser/ShadowRuleBeanDefinitionParser.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/parser/ShadowRuleBeanDefinitionParser.java
index 94f1708..02b58cb 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/parser/ShadowRuleBeanDefinitionParser.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/parser/ShadowRuleBeanDefinitionParser.java
@@ -17,14 +17,26 @@
 
 package org.apache.shardingsphere.shadow.spring.namespace.parser;
 
-import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
-import org.apache.shardingsphere.shadow.spring.namespace.tag.ShadowDataSourceBeanDefinitionParserTag;
+import org.apache.shardingsphere.shadow.algorithm.config.AlgorithmProvidedShadowRuleConfiguration;
+import org.apache.shardingsphere.shadow.api.config.datasource.ShadowDataSourceConfiguration;
+import org.apache.shardingsphere.shadow.api.config.table.ShadowTableConfiguration;
+import org.apache.shardingsphere.shadow.spring.namespace.factorybean.ShadowAlgorithmFactoryBean;
+import org.apache.shardingsphere.shadow.spring.namespace.tag.ShadowRuleBeanDefinitionTag;
+import org.apache.shardingsphere.spring.namespace.registry.ShardingSphereAlgorithmBeanRegistry;
+import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.support.ManagedMap;
 import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
 import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.xml.DomUtils;
 import org.w3c.dom.Element;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
 /**
  * Shadow rule parser for spring namespace.
  */
@@ -38,10 +50,58 @@ public final class ShadowRuleBeanDefinitionParser extends AbstractBeanDefinition
      */
     @Override
     protected AbstractBeanDefinition parseInternal(final Element element, final ParserContext parserContext) {
-        BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(ShadowRuleConfiguration.class);
-        factory.addConstructorArgValue(element.getAttribute(ShadowDataSourceBeanDefinitionParserTag.COLUMN_CONFIG_TAG));
-        factory.addConstructorArgValue(element.getAttribute(ShadowDataSourceBeanDefinitionParserTag.SOURCE_DATASOURCE_NAMES_TAG).split(","));
-        factory.addConstructorArgValue(element.getAttribute(ShadowDataSourceBeanDefinitionParserTag.SHADOW_DATASOURCE_NAMES_TAG).split(","));
+        BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(AlgorithmProvidedShadowRuleConfiguration.class);
+        addConstructorArgValue(element, factory);
+        factory.addPropertyValue("dataSources", parseDataSourcesConfiguration(element));
+        factory.addPropertyValue("shadowTables", parseShadowTablesConfiguration(element));
+        factory.addPropertyValue("shadowAlgorithms", ShardingSphereAlgorithmBeanRegistry.getAlgorithmBeanReferences(parserContext, ShadowAlgorithmFactoryBean.class));
+        return factory.getBeanDefinition();
+    }
+    
+    private Map<String, BeanDefinition> parseShadowTablesConfiguration(final Element element) {
+        List<Element> tableRuleElements = DomUtils.getChildElementsByTagName(element, ShadowRuleBeanDefinitionTag.SHADOW_TABLE_TAG);
+        Map<String, BeanDefinition> result = new ManagedMap<>(tableRuleElements.size());
+        for (Element each : tableRuleElements) {
+            result.put(each.getAttribute(ShadowRuleBeanDefinitionTag.SHADOW_TABLE_NAME_ATTRIBUTE), parseShadowTableConfiguration(each));
+        }
+        return result;
+    }
+    
+    private BeanDefinition parseShadowTableConfiguration(final Element element) {
+        BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(ShadowTableConfiguration.class);
+        factory.addConstructorArgValue(parseShadowAlgorithmNames(element));
         return factory.getBeanDefinition();
     }
+    
+    private Collection<String> parseShadowAlgorithmNames(final Element element) {
+        List<Element> shadowAlgorithmElements = DomUtils.getChildElementsByTagName(element, ShadowRuleBeanDefinitionTag.SHADOW_TABLE_ALGORITHM_TAG);
+        Collection<String> result = new ManagedList<>(shadowAlgorithmElements.size());
+        for (Element each : shadowAlgorithmElements) {
+            result.add(each.getAttribute(ShadowRuleBeanDefinitionTag.SHADOW_TABLE_ALGORITHM_REF_ATTRIBUTE));
+        }
+        return result;
+    }
+    
+    private Map<String, BeanDefinition> parseDataSourcesConfiguration(final Element element) {
+        List<Element> dataSourcesElements = DomUtils.getChildElementsByTagName(element, ShadowRuleBeanDefinitionTag.DATA_SOURCE_TAG);
+        Map<String, BeanDefinition> result = new ManagedMap<>(dataSourcesElements.size());
+        for (Element each : dataSourcesElements) {
+            result.put(each.getAttribute(ShadowRuleBeanDefinitionTag.DATA_SOURCE_ID_ATTRIBUTE), parseDataSourceConfiguration(each));
+        }
+        return result;
+    }
+    
+    private BeanDefinition parseDataSourceConfiguration(final Element element) {
+        BeanDefinitionBuilder factory = BeanDefinitionBuilder.rootBeanDefinition(ShadowDataSourceConfiguration.class);
+        factory.addConstructorArgValue(element.getAttribute(ShadowRuleBeanDefinitionTag.SOURCE_DATA_SOURCE_NAME_ATTRIBUTE));
+        factory.addConstructorArgValue(element.getAttribute(ShadowRuleBeanDefinitionTag.SHADOW_DATA_SOURCE_NAME_ATTRIBUTE));
+        return factory.getBeanDefinition();
+    }
+    
+    // fixme remove method when the api refactoring is complete
+    private void addConstructorArgValue(final Element element, final BeanDefinitionBuilder factory) {
+        factory.addConstructorArgValue(element.getAttribute(ShadowRuleBeanDefinitionTag.COLUMN_CONFIG_TAG));
+        factory.addConstructorArgValue(element.getAttribute(ShadowRuleBeanDefinitionTag.SOURCE_DATASOURCE_NAMES_TAG).split(","));
+        factory.addConstructorArgValue(element.getAttribute(ShadowRuleBeanDefinitionTag.SHADOW_DATASOURCE_NAMES_TAG).split(","));
+    }
 }
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowDataSourceBeanDefinitionParserTag.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowAlgorithmBeanDefinitionTag.java
similarity index 71%
copy from shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowDataSourceBeanDefinitionParserTag.java
copy to shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowAlgorithmBeanDefinitionTag.java
index 0e163aa..64de18e 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowDataSourceBeanDefinitionParserTag.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowAlgorithmBeanDefinitionTag.java
@@ -21,16 +21,10 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 
 /**
- * Shadow data source parser tag constants.
+ * Shadow algorithm bean definition tag.
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class ShadowDataSourceBeanDefinitionParserTag {
+public final class ShadowAlgorithmBeanDefinitionTag {
     
-    public static final String ROOT_TAG = "rule";
-    
-    public static final String COLUMN_CONFIG_TAG = "column";
-    
-    public static final String SHADOW_DATASOURCE_NAMES_TAG = "shadowDataSourceNames";
-    
-    public static final String SOURCE_DATASOURCE_NAMES_TAG = "sourceDataSourceNames";
+    public static final String ROOT_TAG = "shadow-algorithm";
 }
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowDataSourceBeanDefinitionParserTag.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowRuleBeanDefinitionTag.java
similarity index 60%
rename from shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowDataSourceBeanDefinitionParserTag.java
rename to shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowRuleBeanDefinitionTag.java
index 0e163aa..aa1d916 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowDataSourceBeanDefinitionParserTag.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/java/org/apache/shardingsphere/shadow/spring/namespace/tag/ShadowRuleBeanDefinitionTag.java
@@ -21,16 +21,33 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 
 /**
- * Shadow data source parser tag constants.
+ * Shadow rule bean definition tag constants.
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class ShadowDataSourceBeanDefinitionParserTag {
+public final class ShadowRuleBeanDefinitionTag {
     
     public static final String ROOT_TAG = "rule";
     
+    // fixme remove three fields when the api refactoring is complete
     public static final String COLUMN_CONFIG_TAG = "column";
     
     public static final String SHADOW_DATASOURCE_NAMES_TAG = "shadowDataSourceNames";
     
     public static final String SOURCE_DATASOURCE_NAMES_TAG = "sourceDataSourceNames";
+    
+    public static final String DATA_SOURCE_TAG = "data-source";
+    
+    public static final String DATA_SOURCE_ID_ATTRIBUTE = "id";
+    
+    public static final String SOURCE_DATA_SOURCE_NAME_ATTRIBUTE = "source-data-source-name";
+    
+    public static final String SHADOW_DATA_SOURCE_NAME_ATTRIBUTE = "shadow-data-source-name";
+    
+    public static final String SHADOW_TABLE_TAG = "shadow-table";
+    
+    public static final String SHADOW_TABLE_NAME_ATTRIBUTE = "name";
+    
+    public static final String SHADOW_TABLE_ALGORITHM_TAG = "table-algorithm";
+    
+    public static final String SHADOW_TABLE_ALGORITHM_REF_ATTRIBUTE = "shadow-algorithm-ref";
 }
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/resources/META-INF/namespace/shadow.xsd b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/resources/META-INF/namespace/shadow.xsd
index 6d785cd..9985365 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/resources/META-INF/namespace/shadow.xsd
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/resources/META-INF/namespace/shadow.xsd
@@ -18,6 +18,7 @@
 
 <xsd:schema xmlns="http://shardingsphere.apache.org/schema/shardingsphere/shadow"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+            xmlns:beans="http://www.springframework.org/schema/beans"
             targetNamespace="http://shardingsphere.apache.org/schema/shardingsphere/shadow"
             elementFormDefault="qualified">
     <xsd:import namespace="http://www.springframework.org/schema/beans"
@@ -25,14 +26,62 @@
 
     <xsd:element name="rule">
         <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element ref="data-source" minOccurs="0" maxOccurs="unbounded" />
+                <xsd:element ref="shadow-table" minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
             <xsd:attribute name="id" type="xsd:string" use="required"/>
+            <!-- fixme remove when the api refactoring is complete start -->
             <xsd:attribute name="column" type="xsd:string" use="required"/>
             <xsd:attribute name="sourceDataSourceNames" type="list" use="required"/>
             <xsd:attribute name="shadowDataSourceNames" type="list" use="required"/>
+            <!-- fixme remove when the api refactoring is complete end -->
         </xsd:complexType>
     </xsd:element>
 
+    <!-- fixme remove when the api refactoring is complete start -->
     <xsd:simpleType name="list">
         <xsd:list itemType="xsd:string"/>
     </xsd:simpleType>
+    <!-- fixme remove when the api refactoring is complete end -->
+
+    <xsd:element name="data-source">
+        <xsd:complexType>
+            <xsd:attribute name="id" type="xsd:string" use="required"/>
+            <xsd:attribute name="source-data-source-name" type="xsd:string" use="required"/>
+            <xsd:attribute name="shadow-data-source-name" type="xsd:string" use="required"/>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="shadow-table">
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element ref="table-algorithm" maxOccurs="unbounded" />
+            </xsd:sequence>
+            <xsd:attribute name="name" type="xsd:string" use="required"/>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="table-algorithm">
+        <xsd:complexType>
+            <xsd:attribute name="shadow-algorithm-ref" type="xsd:string" use="required"/>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="shadow-algorithm">
+        <xsd:complexType>
+            <xsd:all>
+                <xsd:element ref="beans:props" minOccurs="0" />
+            </xsd:all>
+            <xsd:attribute name="id" type="xsd:string" use="required"/>
+            <xsd:attribute name="type" type="algorithmType" use="required"/>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:simpleType name="algorithmType">
+        <xsd:restriction base="xsd:string">
+            <xsd:enumeration value="COLUMN-REGULAR-MATCH" />
+            <xsd:enumeration value="SIMPLE-NOTE" />
+        </xsd:restriction>
+    </xsd:simpleType>
 </xsd:schema>
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/resources/META-INF/spring.handlers b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/resources/META-INF/spring.handlers
index f37db67..e61baa3 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/resources/META-INF/spring.handlers
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/main/resources/META-INF/spring.handlers
@@ -15,4 +15,4 @@
 # limitations under the License.
 #
 
-http\://shardingsphere.apache.org/schema/shardingsphere/shadow=org.apache.shardingsphere.shadow.spring.namespace.handler.ShadowRuleNamespaceHandler
+http\://shardingsphere.apache.org/schema/shardingsphere/shadow=org.apache.shardingsphere.shadow.spring.namespace.handler.ShadowNamespaceHandler
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/java/org/apache/shardingsphere/shadow/spring/namespace/ShadowAlgorithmSpringNamespaceTest.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/java/org/apache/shardingsphere/shadow/spring/namespace/ShadowAlgorithmSpringNamespaceTest.java
new file mode 100644
index 0000000..b43c27e
--- /dev/null
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/java/org/apache/shardingsphere/shadow/spring/namespace/ShadowAlgorithmSpringNamespaceTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.shadow.spring.namespace;
+
+import org.apache.shardingsphere.shadow.algorithm.ColumnRegularMatchShadowAlgorithm;
+import org.apache.shardingsphere.shadow.algorithm.SimpleSQLNoteShadowAlgorithm;
+import org.apache.shardingsphere.shadow.algorithm.config.AlgorithmProvidedShadowRuleConfiguration;
+import org.apache.shardingsphere.shadow.api.config.datasource.ShadowDataSourceConfiguration;
+import org.apache.shardingsphere.shadow.api.config.table.ShadowTableConfiguration;
+import org.apache.shardingsphere.shadow.spi.ShadowAlgorithm;
+import org.junit.Test;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import javax.annotation.Resource;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+@ContextConfiguration(locations = "classpath:META-INF/spring/shadow-algorithm-application-context.xml")
+public final class ShadowAlgorithmSpringNamespaceTest extends AbstractJUnit4SpringContextTests {
+    
+    @Resource
+    private AlgorithmProvidedShadowRuleConfiguration shadowRule;
+    
+    @Test
+    public void assertDataSource() {
+        assertBasicShadowRule(shadowRule.getColumn(), shadowRule.getSourceDataSourceNames(), shadowRule.getShadowDataSourceNames());
+        assertShadowDataSources(shadowRule.getDataSources());
+        assertShadowTables(shadowRule.getShadowTables());
+        assertShadowAlgorithms(shadowRule.getShadowAlgorithms());
+    }
+    
+    private void assertShadowAlgorithms(final Map<String, ShadowAlgorithm> shadowAlgorithms) {
+        assertThat(shadowAlgorithms.get("columnRegularMatchShadowAlgorithm") instanceof ColumnRegularMatchShadowAlgorithm, is(true));
+        assertThat(shadowAlgorithms.get("noteShadowAlgorithm") instanceof SimpleSQLNoteShadowAlgorithm, is(true));
+    }
+    
+    private void assertShadowTables(final Map<String, ShadowTableConfiguration> shadowTables) {
+        assertThat(shadowTables.size(), is(2));
+        assertThat(shadowTables.get("t_order").getShadowAlgorithmNames(), is(Arrays.asList("columnRegularMatchShadowAlgorithm", "noteShadowAlgorithm")));
+        assertThat(shadowTables.get("t_user").getShadowAlgorithmNames(), is(Arrays.asList("columnRegularMatchShadowAlgorithm", "noteShadowAlgorithm")));
+    }
+    
+    private void assertShadowDataSources(final Map<String, ShadowDataSourceConfiguration> dataSources) {
+        assertThat(dataSources.size(), is(1));
+        assertThat(dataSources.get("shadow-data-source").getSourceDataSourceName(), is("ds"));
+        assertThat(dataSources.get("shadow-data-source").getShadowDataSourceName(), is("ds-shadow"));
+    }
+    
+    // fixme remove method when the api refactoring is complete
+    private void assertBasicShadowRule(final String column, final List<String> sourceDataSourceNames, final List<String> shadowDataSourceNames) {
+        assertThat(column, is("shadow"));
+        assertThat(sourceDataSourceNames, is(Arrays.asList("ds0", "ds1")));
+        assertThat(shadowDataSourceNames, is(Arrays.asList("shadow_ds0", "shadow_ds1")));
+    }
+}
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/java/org/apache/shardingsphere/shadow/spring/namespace/ShadowSpringNamespaceTest.java b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/java/org/apache/shardingsphere/shadow/spring/namespace/ShadowSpringNamespaceTest.java
index 14bdb0b..acfec7e 100644
--- a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/java/org/apache/shardingsphere/shadow/spring/namespace/ShadowSpringNamespaceTest.java
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/java/org/apache/shardingsphere/shadow/spring/namespace/ShadowSpringNamespaceTest.java
@@ -17,27 +17,36 @@
 
 package org.apache.shardingsphere.shadow.spring.namespace;
 
-import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
+import org.apache.shardingsphere.shadow.algorithm.config.AlgorithmProvidedShadowRuleConfiguration;
 import org.junit.Test;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
 
 import javax.annotation.Resource;
 import java.util.Arrays;
+import java.util.List;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 
 @ContextConfiguration(locations = "classpath:META-INF/spring/shadow-application-context.xml")
 public final class ShadowSpringNamespaceTest extends AbstractJUnit4SpringContextTests {
     
     @Resource
-    private ShadowRuleConfiguration shadowRule;
+    private AlgorithmProvidedShadowRuleConfiguration shadowRule;
     
     @Test
     public void assertDataSource() {
-        assertThat(shadowRule.getColumn(), is("shadow"));
-        assertThat(shadowRule.getSourceDataSourceNames(), is(Arrays.asList("ds", "ds1")));
-        assertThat(shadowRule.getShadowDataSourceNames(), is(Arrays.asList("shadow_ds", "shadow_ds1")));
+        assertBasicShadowRule(shadowRule.getColumn(), shadowRule.getSourceDataSourceNames(), shadowRule.getShadowDataSourceNames());
+        assertTrue(shadowRule.getDataSources().isEmpty());
+        assertTrue(shadowRule.getShadowTables().isEmpty());
+        assertTrue(shadowRule.getShadowAlgorithms().isEmpty());
+    }
+    
+    private void assertBasicShadowRule(final String column, final List<String> sourceDataSourceNames, final List<String> shadowDataSourceNames) {
+        assertThat(column, is("shadow"));
+        assertThat(sourceDataSourceNames, is(Arrays.asList("ds", "ds1")));
+        assertThat(shadowDataSourceNames, is(Arrays.asList("shadow_ds", "shadow_ds1")));
     }
 }
diff --git a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/resources/META-INF/spring/shadow-algorithm-application-context.xml b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/resources/META-INF/spring/shadow-algorithm-application-context.xml
new file mode 100644
index 0000000..c67cf83
--- /dev/null
+++ b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-spring/shardingsphere-shadow-spring-namespace/src/test/resources/META-INF/spring/shadow-algorithm-application-context.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  -->
+
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:shadow="http://shardingsphere.apache.org/schema/shardingsphere/shadow"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans 
+                           http://www.springframework.org/schema/beans/spring-beans.xsd
+                           http://shardingsphere.apache.org/schema/shardingsphere/shadow
+                           http://shardingsphere.apache.org/schema/shardingsphere/shadow/shadow.xsd
+                           ">
+
+    <shadow:shadow-algorithm id="columnRegularMatchShadowAlgorithm" type="COLUMN-REGULAR-MATCH">
+        <props>
+            <prop key="column">user_id</prop>
+            <prop key="regex">[a]</prop>
+            <prop key="operation">UPDATE</prop>
+        </props>
+    </shadow:shadow-algorithm>
+    <shadow:shadow-algorithm id="noteShadowAlgorithm" type="SIMPLE-NOTE">
+        <props>
+            <prop key="shadow">true</prop>
+        </props>
+    </shadow:shadow-algorithm>
+
+    <shadow:rule id="shadowRule" column="shadow" sourceDataSourceNames="ds0,ds1" shadowDataSourceNames="shadow_ds0,shadow_ds1">
+        <shadow:data-source id="shadow-data-source" source-data-source-name="ds" shadow-data-source-name="ds-shadow"/>
+        <shadow:shadow-table name="t_order">
+            <shadow:table-algorithm shadow-algorithm-ref= "columnRegularMatchShadowAlgorithm" />
+            <shadow:table-algorithm shadow-algorithm-ref= "noteShadowAlgorithm" />
+        </shadow:shadow-table>
+        <shadow:shadow-table name="t_user">
+            <shadow:table-algorithm shadow-algorithm-ref= "columnRegularMatchShadowAlgorithm" />
+            <shadow:table-algorithm shadow-algorithm-ref= "noteShadowAlgorithm" />
+        </shadow:shadow-table>
+    </shadow:rule>
+</beans>