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

jianbin pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/incubator-seata.git


The following commit(s) were added to refs/heads/2.x by this push:
     new 167984918d optimize: branch register resource only at RM server end 
(#5399)
167984918d is described below

commit 167984918d4f0ea887ce0680bd69edfe51132ba0
Author: sunrui1225 <srs_1...@163.com>
AuthorDate: Mon Jan 8 13:58:44 2024 +0800

    optimize: branch register resource only at RM server end (#5399)
---
 changes/en-us/2.x.md                               |   3 +
 changes/zh-cn/2.x.md                               |   5 +-
 .../interceptor/parser/DefaultInterfaceParser.java |  12 +++
 .../GlobalTransactionalInterceptorParser.java      |  14 +++
 ...InterfaceParser.java => IfNeedEnhanceBean.java} |  69 ++++++++------
 .../tx/api/interceptor/parser/InterfaceParser.java |   2 +
 .../{InterfaceParser.java => NeedEnhanceEnum.java} |  58 ++++++------
 .../tx/api/remoting/RemotingParser.java            |   9 ++
 .../api/remoting/parser/DefaultRemotingParser.java |  15 +++
 .../api/remoting/parser/DubboRemotingParser.java   |   6 ++
 .../tx/api/remoting/parser/HSFRemotingParser.java  |   6 ++
 .../api/remoting/parser/SofaRpcRemotingParser.java |   6 ++
 .../seata/integration/tx/api/util/ProxyUtil.java   |  15 +++
 .../java/io/seata/rm/fence/SpringFenceHandler.java |  12 ++-
 .../annotation/GlobalTransactionScanner.java       |  74 +++++++++++++++
 .../remoting/parser/RemotingFactoryBeanParser.java |   5 +
 .../interceptor/TccActionInterceptorHandler.java   |  11 +--
 .../parser/TccActionInterceptorParser.java         |  64 ++++++-------
 .../remoting/parser/LocalTCCRemotingParser.java    |   9 ++
 .../resource/parser/TccRegisterResourceParser.java | 102 +++++++++------------
 20 files changed, 342 insertions(+), 155 deletions(-)

diff --git a/changes/en-us/2.x.md b/changes/en-us/2.x.md
index 64b45f46e3..240fcf7dec 100644
--- a/changes/en-us/2.x.md
+++ b/changes/en-us/2.x.md
@@ -39,6 +39,7 @@ Add changes here for all PR submitted to the 2.x branch.
 - [[#6184](https://github.com/apache/incubator-seata/pull/6184)] update NOTICE 
file
 - [[#6192](https://github.com/apache/incubator-seata/pull/6192)] remove the 
useless file
 - [[#6194](https://github.com/apache/incubator-seata/pull/6194)] fix asf.yaml 
parse error
+- [[#5399](https://github.com/apache/incubator-seata/pull/5399)] optimizing 
branch register resource only at RM server end
 - [[#6154](https://github.com/apache/incubator-seata/pull/6154)] console log 
optimize for "kubectl logs -f"
 - [[#6116](https://github.com/apache/incubator-seata/pull/6116)] rewrite 
NettyPoolKey's hashcode and equals to fix duplicate construction of channel 
object pools
 - [[#6195](https://github.com/apache/incubator-seata/pull/6195)] update the 
url in change log to apache/incubator-seata
@@ -78,10 +79,12 @@ Thanks to these contributors for their code commits. Please 
report an unintended
 - [lightClouds917](https://github.com/lightClouds917)
 - [xingfudeshi](https://github.com/xingfudeshi)
 - [PleaseGiveMeTheCoke](https://github.com/PleaseGiveMeTheCoke)
+- [sunrui1225](https://github.com/sunrui1225)
 - [PeppaO](https://github.com/PeppaO)
 - [AlbumenJ](https://github.com/AlbumenJ)
 - [dreamskyvision](https://github.com/dreamskyvision)
 - [jsbxyyx](https://github.com/jsbxyyx)
 - [liuqiufeng](https://github.com/liuqiufeng)
 
+
 Also, we receive many valuable issues, questions and advices from our 
community. Thanks for you all.
diff --git a/changes/zh-cn/2.x.md b/changes/zh-cn/2.x.md
index 84fe561a2f..55f930c8ff 100644
--- a/changes/zh-cn/2.x.md
+++ b/changes/zh-cn/2.x.md
@@ -38,7 +38,7 @@
 - [[#6184](https://github.com/apache/incubator-seata/pull/6184)] 更新NOTICE文件
 - [[#6192](https://github.com/apache/incubator-seata/pull/6192)] 移除无用文件
 - [[#6194](https://github.com/apache/incubator-seata/pull/6194)] 修复 asf.yaml 
解析错误问题
-- [[#6116](https://github.com/apache/incubator-seata/pull/6116)] 
重写NettyPoolKey的hashcode和equals,修复了channel对象池重复构建问题
+- [[#5399](https://github.com/apache/incubator-seata/pull/5399)] 分支注册只在RM端
 - [[#6154](https://github.com/apache/incubator-seata/pull/6154)] 控制台日志优化 
"kubectl logs -f"
 - [[#6116](https://github.com/apache/incubator-seata/pull/6116)] 
重写NettyPoolKey的hashcode和equals,修复了channel对象池重复构建问题
 - [[#6195](https://github.com/apache/incubator-seata/pull/6195)] 更新 change log 
中的 seata url 为 apache/incubator-seata
@@ -49,6 +49,7 @@
 - [[#6004](https://github.com/apache/incubator-seata/pull/6004)] 
优化RM,TM连接server快速失败
 - [[#6243](https://github.com/apache/incubator-seata/pull/6243)] 优化控制台页眉中的链接
 
+
 ### security:
 - [[#6069](https://github.com/apache/incubator-seata/pull/6069)] 
升级Guava依赖版本,修复安全漏洞
 - [[#6144](https://github.com/apache/incubator-seata/pull/6144)] 
升级Nacos依赖版本至1.4.6
@@ -78,10 +79,12 @@
 - [lightClouds917](https://github.com/lightClouds917)
 - [xingfudeshi](https://github.com/xingfudeshi)
 - [PleaseGiveMeTheCoke](https://github.com/PleaseGiveMeTheCoke)
+- [sunrui1225](https://github.com/sunrui1225)
 - [PeppaO](https://github.com/PeppaO)
 - [AlbumenJ](https://github.com/AlbumenJ)
 - [dreamskyvision](https://github.com/dreamskyvision)
 - [jsbxyyx](https://github.com/jsbxyyx)
 - [liuqiufeng](https://github.com/liuqiufeng)
 
+
 同时,我们收到了社区反馈的很多有价值的issue和建议,非常感谢大家。
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/DefaultInterfaceParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/DefaultInterfaceParser.java
index 89f8499db8..7474ef4a6d 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/DefaultInterfaceParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/DefaultInterfaceParser.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 /**
+ * @author leezongjie
  */
 public class DefaultInterfaceParser implements InterfaceParser {
 
@@ -63,4 +64,15 @@ public class DefaultInterfaceParser implements 
InterfaceParser {
         return null;
     }
 
+    @Override
+    public IfNeedEnhanceBean parseIfNeedEnhancement(Class<?> beanClass) {
+        for (InterfaceParser interfaceParser : ALL_INTERFACE_PARSERS) {
+            IfNeedEnhanceBean ifNeedEnhanceBean = 
interfaceParser.parseIfNeedEnhancement(beanClass);
+            if (ifNeedEnhanceBean.isIfNeed()) {
+                return ifNeedEnhanceBean;
+            }
+        }
+        return new IfNeedEnhanceBean();
+    }
+
 }
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
index 5bb44043b8..9b01e92a2f 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/GlobalTransactionalInterceptorParser.java
@@ -22,6 +22,7 @@ import java.util.Set;
 
 import io.seata.common.ConfigurationKeys;
 import io.seata.common.util.CollectionUtils;
+import io.seata.common.util.ReflectionUtil;
 import io.seata.config.ConfigurationCache;
 import io.seata.config.ConfigurationChangeListener;
 import 
io.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler;
@@ -59,6 +60,19 @@ public class GlobalTransactionalInterceptorParser implements 
InterfaceParser {
         return null;
     }
 
+    @Override
+    public IfNeedEnhanceBean parseIfNeedEnhancement(Class<?> beanClass) {
+        Set<Class<?>> interfaceClasses = 
ReflectionUtil.getInterfaces(beanClass);
+        Class<?>[] interfaceClasseArray = interfaceClasses.toArray(new 
Class<?>[0]);
+
+        IfNeedEnhanceBean ifNeedEnhanceBean = new IfNeedEnhanceBean();
+        if (existsAnnotation(beanClass) || 
existsAnnotation(interfaceClasseArray)) {
+            ifNeedEnhanceBean.setIfNeed(true);
+            
ifNeedEnhanceBean.setNeedEnhanceEnum(NeedEnhanceEnum.GLOBAL_TRANSACTIONAL_BEAN);
+        }
+        return ifNeedEnhanceBean;
+    }
+
     private boolean existsAnnotation(Class<?>... classes) {
         boolean result = false;
         if (CollectionUtils.isNotEmpty(classes)) {
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/IfNeedEnhanceBean.java
similarity index 63%
copy from 
integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
copy to 
integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/IfNeedEnhanceBean.java
index 23db3c4a2e..c0d1e91737 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/IfNeedEnhanceBean.java
@@ -1,28 +1,41 @@
-/*
- * 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 io.seata.integration.tx.api.interceptor.parser;
-
-import io.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
-
-/**
- */
-public interface InterfaceParser {
-
-    ProxyInvocationHandler parserInterfaceToProxy(Object target, String 
objectName) throws Exception;
-
-
-}
+/*
+ * 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 io.seata.integration.tx.api.interceptor.parser;
+
+public class IfNeedEnhanceBean {
+
+    private boolean ifNeed;
+
+    private NeedEnhanceEnum needEnhanceEnum;
+
+    public boolean isIfNeed() {
+        return ifNeed;
+    }
+
+    public void setIfNeed(boolean ifNeed) {
+        this.ifNeed = ifNeed;
+    }
+
+    public NeedEnhanceEnum getNeedEnhanceEnum() {
+        return needEnhanceEnum;
+    }
+
+    public void setNeedEnhanceEnum(NeedEnhanceEnum needEnhanceEnum) {
+        this.needEnhanceEnum = needEnhanceEnum;
+    }
+
+}
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
index 23db3c4a2e..2584c6459e 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
@@ -24,5 +24,7 @@ public interface InterfaceParser {
 
     ProxyInvocationHandler parserInterfaceToProxy(Object target, String 
objectName) throws Exception;
 
+    IfNeedEnhanceBean parseIfNeedEnhancement(Class<?> beanClass);
+
 
 }
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/NeedEnhanceEnum.java
similarity index 79%
copy from 
integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
copy to 
integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/NeedEnhanceEnum.java
index 23db3c4a2e..7ac30889c7 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/InterfaceParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/interceptor/parser/NeedEnhanceEnum.java
@@ -1,28 +1,30 @@
-/*
- * 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 io.seata.integration.tx.api.interceptor.parser;
-
-import io.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
-
-/**
- */
-public interface InterfaceParser {
-
-    ProxyInvocationHandler parserInterfaceToProxy(Object target, String 
objectName) throws Exception;
-
-
-}
+/*
+ * 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 io.seata.integration.tx.api.interceptor.parser;
+
+
+public enum NeedEnhanceEnum {
+
+    /**
+     * global transactional bean type
+     */
+    GLOBAL_TRANSACTIONAL_BEAN,
+    /**
+     * service bean type
+     */
+    SERVICE_BEAN;
+}
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/RemotingParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/RemotingParser.java
index 569f5749ad..71664b0542 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/RemotingParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/RemotingParser.java
@@ -54,6 +54,15 @@ public interface RemotingParser {
      */
     boolean isService(Object bean, String beanName) throws FrameworkException;
 
+    /**
+     * if it is service bean ?
+     *
+     * @param beanClass the bean class
+     * @return boolean boolean
+     * @throws FrameworkException the framework exception
+     */
+    boolean isService(Class<?> beanClass) throws FrameworkException;
+
     /**
      * get the remoting bean info
      *
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/DefaultRemotingParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/DefaultRemotingParser.java
index f3f8eafab4..e1ca71b622 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/DefaultRemotingParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/DefaultRemotingParser.java
@@ -132,6 +132,21 @@ public class DefaultRemotingParser {
         return false;
     }
 
+    /**
+     * is service bean ?
+     *
+     * @param beanClass the bean class
+     * @return boolean boolean
+     */
+    public boolean isService(Class<?> beanClass) {
+        for (RemotingParser remotingParser : allRemotingParsers) {
+            if (remotingParser.isService(beanClass)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * get the remoting Service desc
      *
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/DubboRemotingParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/DubboRemotingParser.java
index 681e096ad9..4014cd5e8c 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/DubboRemotingParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/DubboRemotingParser.java
@@ -41,6 +41,12 @@ public class DubboRemotingParser extends 
AbstractedRemotingParser {
                 || 
"org.apache.dubbo.config.spring.ServiceBean".equals(c.getName());
     }
 
+    @Override
+    public boolean isService(Class<?> beanClass) throws FrameworkException {
+        return 
"com.alibaba.dubbo.config.spring.ServiceBean".equals(beanClass.getName())
+                || 
"org.apache.dubbo.config.spring.ServiceBean".equals(beanClass.getName());
+    }
+
     @Override
     public RemotingDesc getServiceDesc(Object bean, String beanName) throws 
FrameworkException {
         if (!this.isRemoting(bean, beanName)) {
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/HSFRemotingParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/HSFRemotingParser.java
index aa76a40353..4818f127d4 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/HSFRemotingParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/HSFRemotingParser.java
@@ -64,6 +64,12 @@ public class HSFRemotingParser extends 
AbstractedRemotingParser {
         return isHsf && 
"com.taobao.hsf.app.spring.util.HSFSpringProviderBean".equals(beanClassName);
     }
 
+    @Override
+    public boolean isService(Class<?> beanClass) throws FrameworkException {
+        String beanClassName = beanClass.getName();
+        return isHsf && 
"com.taobao.hsf.app.spring.util.HSFSpringProviderBean".equals(beanClassName);
+    }
+
     @Override
     public RemotingDesc getServiceDesc(Object bean, String beanName) throws 
FrameworkException {
         if (!this.isRemoting(bean, beanName)) {
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/SofaRpcRemotingParser.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/SofaRpcRemotingParser.java
index a5872ba133..4cb03f709d 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/SofaRpcRemotingParser.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/remoting/parser/SofaRpcRemotingParser.java
@@ -42,6 +42,12 @@ public class SofaRpcRemotingParser extends 
AbstractedRemotingParser {
         return 
"com.alipay.sofa.runtime.spring.factory.ServiceFactoryBean".equals(beanClassName);
     }
 
+    @Override
+    public boolean isService(Class<?> beanClass) throws FrameworkException {
+        String beanClassName = beanClass.getName();
+        return 
"com.alipay.sofa.runtime.spring.factory.ServiceFactoryBean".equals(beanClassName);
+    }
+
     @Override
     public RemotingDesc getServiceDesc(Object bean, String beanName) throws 
FrameworkException {
         if (!this.isRemoting(bean, beanName)) {
diff --git 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/util/ProxyUtil.java
 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/util/ProxyUtil.java
index 8588803384..9efbf8b0f0 100644
--- 
a/integration-tx-api/src/main/java/io/seata/integration/tx/api/util/ProxyUtil.java
+++ 
b/integration-tx-api/src/main/java/io/seata/integration/tx/api/util/ProxyUtil.java
@@ -37,6 +37,21 @@ public class ProxyUtil {
         return createProxy(target, target.getClass().getName());
     }
 
+    /**
+     * The API for generating proxy for target. It can be used by spring aop, 
or
+     * provide user to generate proxy manually.
+     * <p>
+     * At TM side, It can be used for the target bean with 
@GlobalTransactional or @GlobalLock to generate proxy which start global 
transaction.
+     * At RM side, if you use TCC mode, It can be for target bean with 
@TwoPhaseBusinessAction to generate proxy which register branch source
+     *      and branch transaction. If you want to use this API to generate 
proxy manual like dubbo, you must make sure the target bean is the
+     *      business bean with @GlobalTransactional annotation. If you pass 
the ServiceBean(com.alibaba.dubbo.config.spring.ServiceBean) or
+     *      ReferenceBean(com.alibaba.dubbo.config.spring.ReferenceBean), it 
will don't work.
+     *
+     * @param target    the business bean
+     * @param beanName  the business bean name
+     * @return          the proxy bean
+     * @param <T>       the generics class
+     */
     public static <T> T createProxy(T target, String beanName) {
         try {
             synchronized (PROXYED_SET) {
diff --git a/spring/src/main/java/io/seata/rm/fence/SpringFenceHandler.java 
b/spring/src/main/java/io/seata/rm/fence/SpringFenceHandler.java
index 1fd56e7992..e657605432 100644
--- a/spring/src/main/java/io/seata/rm/fence/SpringFenceHandler.java
+++ b/spring/src/main/java/io/seata/rm/fence/SpringFenceHandler.java
@@ -163,7 +163,9 @@ public class SpringFenceHandler implements FenceHandler {
                     }
                     return false;
                 }
-                return updateStatusAndInvokeTargetMethod(conn, commitMethod, 
targetTCCBean, xid, branchId, CommonFenceConstant.STATUS_COMMITTED, status, 
args);
+                boolean result = updateStatusAndInvokeTargetMethod(conn, 
commitMethod, targetTCCBean, xid, branchId, 
CommonFenceConstant.STATUS_COMMITTED, status, args);
+                LOGGER.info("Common fence commit result: {}. xid: {}, 
branchId: {}", result, xid, branchId);
+                return result;
             } catch (Throwable t) {
                 status.setRollbackOnly();
                 throw new SkipCallbackWrapperException(t);
@@ -210,7 +212,9 @@ public class SpringFenceHandler implements FenceHandler {
                         return false;
                     }
                 }
-                return updateStatusAndInvokeTargetMethod(conn, rollbackMethod, 
targetTCCBean, xid, branchId, CommonFenceConstant.STATUS_ROLLBACKED, status, 
args);
+                boolean result = updateStatusAndInvokeTargetMethod(conn, 
rollbackMethod, targetTCCBean, xid, branchId, 
CommonFenceConstant.STATUS_ROLLBACKED, status, args);
+                LOGGER.info("Common fence rollback result: {}. xid: {}, 
branchId: {}", result, xid, branchId);
+                return result;
             } catch (Throwable t) {
                 status.setRollbackOnly();
                 throw new SkipCallbackWrapperException(t);
@@ -237,13 +241,13 @@ public class SpringFenceHandler implements FenceHandler {
     }
 
     /**
-     * Update TCC Fence status and invoke target method
+     * Update Common Fence status and invoke target method
      *
      * @param method                target method
      * @param targetTCCBean         target bean
      * @param xid                   the global transaction id
      * @param branchId              the branch transaction id
-     * @param status                the tcc fence status
+     * @param status                the common fence status
      * @return the boolean
      */
     private static boolean updateStatusAndInvokeTargetMethod(Connection conn, 
Method method, Object targetTCCBean,
diff --git 
a/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java 
b/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java
index f37b6117be..916d3dd1aa 100644
--- 
a/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java
+++ 
b/spring/src/main/java/io/seata/spring/annotation/GlobalTransactionScanner.java
@@ -25,6 +25,7 @@ import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 import javax.annotation.Nullable;
 
+import com.google.common.collect.ImmutableSet;
 import io.seata.common.util.CollectionUtils;
 import io.seata.common.util.StringUtils;
 import io.seata.config.ConfigurationCache;
@@ -42,6 +43,8 @@ import 
io.seata.integration.tx.api.interceptor.SeataInterceptorPosition;
 import 
io.seata.integration.tx.api.interceptor.handler.GlobalTransactionalInterceptorHandler;
 import io.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
 import io.seata.integration.tx.api.interceptor.parser.DefaultInterfaceParser;
+import io.seata.integration.tx.api.interceptor.parser.IfNeedEnhanceBean;
+import io.seata.integration.tx.api.interceptor.parser.NeedEnhanceEnum;
 import io.seata.integration.tx.api.remoting.parser.DefaultRemotingParser;
 import io.seata.rm.RMClient;
 import io.seata.spring.annotation.scannercheckers.PackageScannerChecker;
@@ -62,10 +65,13 @@ import org.springframework.aop.framework.AdvisedSupport;
 import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
 import org.springframework.aop.support.AopUtils;
 import org.springframework.beans.BeansException;
+import org.springframework.beans.PropertyValue;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.beans.factory.FactoryBean;
 import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.config.BeanDefinition;
 import 
org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.ConfigurableApplicationContext;
@@ -114,6 +120,8 @@ public class GlobalTransactionScanner extends 
AbstractAutoProxyCreator
 
     private ApplicationContext applicationContext;
 
+    private static final Set<String> NEED_ENHANCE_BEAN_NAME_SET = new 
HashSet<>();
+
 
     /**
      * Instantiates a new Global transaction scanner.
@@ -280,6 +288,9 @@ public class GlobalTransactionScanner extends 
AbstractAutoProxyCreator
                 if (PROXYED_SET.contains(beanName)) {
                     return bean;
                 }
+                if (!NEED_ENHANCE_BEAN_NAME_SET.contains(beanName)) {
+                    return bean;
+                }
                 interceptor = null;
                 ProxyInvocationHandler proxyInvocationHandler = 
DefaultInterfaceParser.get().parserInterfaceToProxy(bean, beanName);
                 if (proxyInvocationHandler == null) {
@@ -469,8 +480,71 @@ public class GlobalTransactionScanner extends 
AbstractAutoProxyCreator
         if (initialized.compareAndSet(false, true)) {
             initClient();
         }
+
+        this.findBusinessBeanNamesNeededEnhancement();
     }
 
+    private void findBusinessBeanNamesNeededEnhancement() {
+        if (applicationContext instanceof ConfigurableApplicationContext) {
+            ConfigurableApplicationContext configurableApplicationContext = 
(ConfigurableApplicationContext) applicationContext;
+            ConfigurableListableBeanFactory configurableListableBeanFactory = 
configurableApplicationContext.getBeanFactory();
+
+            String[] beanNames = applicationContext.getBeanDefinitionNames();
+            for (String contextBeanName : beanNames) {
+                BeanDefinition beanDefinition = 
configurableListableBeanFactory.getBeanDefinition(contextBeanName);
+                if (StringUtils.isBlank(beanDefinition.getBeanClassName())) {
+                    continue;
+                }
+                if 
(IGNORE_ENHANCE_CHECK_SET.contains(beanDefinition.getBeanClassName())) {
+                    continue;
+                }
+                try {
+                    // get the class by bean definition class name
+                    Class<?> beanClass = 
Class.forName(beanDefinition.getBeanClassName());
+                    // check if it needs enhancement by the class
+                    IfNeedEnhanceBean ifNeedEnhanceBean = 
DefaultInterfaceParser.get().parseIfNeedEnhancement(beanClass);
+                    if (!ifNeedEnhanceBean.isIfNeed()) {
+                        continue;
+                    }
+                    if 
(ifNeedEnhanceBean.getNeedEnhanceEnum().equals(NeedEnhanceEnum.SERVICE_BEAN)) {
+                        // the native bean which dubbo, sofa bean service bean 
referenced
+                        PropertyValue propertyValue = 
beanDefinition.getPropertyValues().getPropertyValue("ref");
+                        if (propertyValue == null) {
+                            // the native bean which HSF service bean 
referenced
+                            propertyValue = 
beanDefinition.getPropertyValues().getPropertyValue("target");
+                        }
+                        if (propertyValue != null) {
+                            RuntimeBeanReference r = (RuntimeBeanReference) 
propertyValue.getValue();
+                            if (r != null && 
StringUtils.isNotBlank(r.getBeanName())) {
+                                
NEED_ENHANCE_BEAN_NAME_SET.add(r.getBeanName());
+                                continue;
+                            }
+                        }
+                        // the native bean which local tcc service bean 
referenced
+                        NEED_ENHANCE_BEAN_NAME_SET.add(contextBeanName);
+                    } else if 
(ifNeedEnhanceBean.getNeedEnhanceEnum().equals(NeedEnhanceEnum.GLOBAL_TRANSACTIONAL_BEAN))
 {
+                        // global transactional bean
+                        NEED_ENHANCE_BEAN_NAME_SET.add(contextBeanName);
+                    }
+                } catch (ClassNotFoundException e) {
+                    LOGGER.warn("check if need enhance bean error, it can be 
ignore", e);
+                }
+            }
+            LOGGER.info("The needed enhancement business beans are : {}", 
NEED_ENHANCE_BEAN_NAME_SET);
+        }
+    }
+
+    private static final Set<String> IGNORE_ENHANCE_CHECK_SET = 
ImmutableSet.of(
+            "io.seata.spring.annotation.GlobalTransactionScanner"
+            , "io.seata.rm.fence.SpringFenceConfig"
+            , 
"org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
+            , 
"org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
+            , 
"org.springframework.context.annotation.internalCommonAnnotationProcessor"
+            , 
"org.springframework.context.event.internalEventListenerProcessor"
+            , "org.springframework.context.event.internalEventListenerFactory"
+    );
+
+
     @Override
     public void setApplicationContext(ApplicationContext applicationContext) 
throws BeansException {
         this.applicationContext = applicationContext;
diff --git 
a/spring/src/main/java/io/seata/spring/remoting/parser/RemotingFactoryBeanParser.java
 
b/spring/src/main/java/io/seata/spring/remoting/parser/RemotingFactoryBeanParser.java
index a5635fbbbf..052061e1c3 100644
--- 
a/spring/src/main/java/io/seata/spring/remoting/parser/RemotingFactoryBeanParser.java
+++ 
b/spring/src/main/java/io/seata/spring/remoting/parser/RemotingFactoryBeanParser.java
@@ -73,6 +73,11 @@ public class RemotingFactoryBeanParser extends 
AbstractedRemotingParser {
         return DefaultRemotingParser.get().isService(factoryBean, 
getFactoryBeanName(beanName));
     }
 
+    @Override
+    public boolean isService(Class<?> beanClass) throws FrameworkException {
+        return false;
+    }
+
     @Override
     public RemotingDesc getServiceDesc(Object bean, String beanName) throws 
FrameworkException {
         Object factoryBean = getRemotingFactoryBean(bean, beanName);
diff --git 
a/tcc/src/main/java/io/seata/rm/tcc/interceptor/TccActionInterceptorHandler.java
 
b/tcc/src/main/java/io/seata/rm/tcc/interceptor/TccActionInterceptorHandler.java
index bbdffe0c7e..db611a8052 100644
--- 
a/tcc/src/main/java/io/seata/rm/tcc/interceptor/TccActionInterceptorHandler.java
+++ 
b/tcc/src/main/java/io/seata/rm/tcc/interceptor/TccActionInterceptorHandler.java
@@ -35,7 +35,6 @@ import 
io.seata.integration.tx.api.interceptor.InvocationWrapper;
 import io.seata.integration.tx.api.interceptor.SeataInterceptorPosition;
 import io.seata.integration.tx.api.interceptor.TwoPhaseBusinessActionParam;
 import 
io.seata.integration.tx.api.interceptor.handler.AbstractProxyInvocationHandler;
-import io.seata.integration.tx.api.remoting.RemotingDesc;
 import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
 import org.slf4j.MDC;
 
@@ -52,12 +51,12 @@ public class TccActionInterceptorHandler extends 
AbstractProxyInvocationHandler
     private ActionInterceptorHandler actionInterceptorHandler = new 
ActionInterceptorHandler();
 
     private Set<String> methodsToProxy;
-    private RemotingDesc remotingDesc;
+    private Object targetBean;
 
     private Map<Method, TwoPhaseBusinessAction> parseAnnotationCache = new 
ConcurrentHashMap<>();
 
-    public TccActionInterceptorHandler(RemotingDesc remotingDesc, Set<String> 
methodsToProxy) {
-        this.remotingDesc = remotingDesc;
+    public TccActionInterceptorHandler(Object targetBean, Set<String> 
methodsToProxy) {
+        this.targetBean = targetBean;
         this.methodsToProxy = methodsToProxy;
     }
 
@@ -113,8 +112,8 @@ public class TccActionInterceptorHandler extends 
AbstractProxyInvocationHandler
     private TwoPhaseBusinessAction parseAnnotation(Method methodKey) throws 
NoSuchMethodException {
         TwoPhaseBusinessAction result = 
parseAnnotationCache.computeIfAbsent(methodKey, method -> {
             TwoPhaseBusinessAction businessAction = 
method.getAnnotation(TwoPhaseBusinessAction.class);
-            if (businessAction == null && remotingDesc.getServiceClass() != 
null) {
-                Set<Class<?>> interfaceClasses = 
ReflectionUtil.getInterfaces(remotingDesc.getServiceClass());
+            if (businessAction == null && targetBean.getClass() != null) {
+                Set<Class<?>> interfaceClasses = 
ReflectionUtil.getInterfaces(targetBean.getClass());
                 if (interfaceClasses != null) {
                     for (Class<?> interClass : interfaceClasses) {
                         try {
diff --git 
a/tcc/src/main/java/io/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java
 
b/tcc/src/main/java/io/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java
index 6496df4a87..d28b6d3e2d 100644
--- 
a/tcc/src/main/java/io/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java
+++ 
b/tcc/src/main/java/io/seata/rm/tcc/interceptor/parser/TccActionInterceptorParser.java
@@ -16,61 +16,63 @@
  */
 package io.seata.rm.tcc.interceptor.parser;
 
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
 import io.seata.common.util.ReflectionUtil;
-import io.seata.integration.tx.api.interceptor.TxBeanParserUtils;
 import io.seata.integration.tx.api.interceptor.handler.ProxyInvocationHandler;
 import 
io.seata.integration.tx.api.interceptor.parser.DefaultResourceRegisterParser;
+import io.seata.integration.tx.api.interceptor.parser.IfNeedEnhanceBean;
 import io.seata.integration.tx.api.interceptor.parser.InterfaceParser;
-import io.seata.integration.tx.api.remoting.RemotingDesc;
+import io.seata.integration.tx.api.interceptor.parser.NeedEnhanceEnum;
 import io.seata.integration.tx.api.remoting.parser.DefaultRemotingParser;
 import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
 import io.seata.rm.tcc.interceptor.TccActionInterceptorHandler;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  */
 public class TccActionInterceptorParser implements InterfaceParser {
 
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(TccActionInterceptorParser.class);
+
     @Override
     public ProxyInvocationHandler parserInterfaceToProxy(Object target, String 
objectName) {
-        boolean isTxRemotingBean = TxBeanParserUtils.isTxRemotingBean(target, 
objectName);
-        if (isTxRemotingBean) {
-            RemotingDesc remotingDesc = 
DefaultRemotingParser.get().getRemotingBeanDesc(target);
-            if (remotingDesc != null) {
-                if (remotingDesc.isService()) {
-                    
DefaultResourceRegisterParser.get().registerResource(target, objectName);
-                }
-                if (remotingDesc.isReference()) {
-                    //if it is a tcc remote reference
-                    Set<String> methodsToProxy = 
tccProxyTargetMethod(remotingDesc);
-                    if (remotingDesc != null && !methodsToProxy.isEmpty()) {
-                        ProxyInvocationHandler proxyInvocationHandler = new 
TccActionInterceptorHandler(remotingDesc, methodsToProxy);
-                        return proxyInvocationHandler;
-                    }
-                }
-            }
+        // eliminate the bean without two phase annotation.
+        Set<String> methodsToProxy = this.tccProxyTargetMethod(target);
+        if (methodsToProxy.isEmpty()) {
+            return null;
         }
-        return null;
+        // register resource and enhance with interceptor
+        DefaultResourceRegisterParser.get().registerResource(target, 
objectName);
+        return new TccActionInterceptorHandler(target, methodsToProxy);
+    }
+
+    @Override
+    public IfNeedEnhanceBean parseIfNeedEnhancement(Class<?> beanClass) {
+        IfNeedEnhanceBean ifNeedEnhanceBean = new IfNeedEnhanceBean();
+        if (DefaultRemotingParser.get().isService(beanClass)) {
+            ifNeedEnhanceBean.setIfNeed(true);
+            ifNeedEnhanceBean.setNeedEnhanceEnum(NeedEnhanceEnum.SERVICE_BEAN);
+        }
+        return ifNeedEnhanceBean;
     }
 
     /**
      * is TCC proxy-bean/target-bean: LocalTCC , the proxy bean of 
sofa:reference/dubbo:reference
      *
-     * @param remotingDesc the remoting desc
+     * @param target the remoting desc
      * @return boolean boolean
      */
-    private Set<String> tccProxyTargetMethod(RemotingDesc remotingDesc) {
-        if (!remotingDesc.isReference() || remotingDesc == null) {
-            return Collections.emptySet();
-        }
+
+    private Set<String> tccProxyTargetMethod(Object target) {
         Set<String> methodsToProxy = new HashSet<>();
         //check if it is TCC bean
-        Class<?> tccServiceClazz = remotingDesc.getServiceClass();
+        Class<?> tccServiceClazz = target.getClass();
         Set<Method> methods = new 
HashSet<>(Arrays.asList(tccServiceClazz.getMethods()));
         Set<Class<?>> interfaceClasses = 
ReflectionUtil.getInterfaces(tccServiceClazz);
         if (interfaceClasses != null) {
diff --git 
a/tcc/src/main/java/io/seata/rm/tcc/remoting/parser/LocalTCCRemotingParser.java 
b/tcc/src/main/java/io/seata/rm/tcc/remoting/parser/LocalTCCRemotingParser.java
index 07a8b9214f..f786924ffa 100644
--- 
a/tcc/src/main/java/io/seata/rm/tcc/remoting/parser/LocalTCCRemotingParser.java
+++ 
b/tcc/src/main/java/io/seata/rm/tcc/remoting/parser/LocalTCCRemotingParser.java
@@ -42,6 +42,11 @@ public class LocalTCCRemotingParser extends 
AbstractedRemotingParser {
         return isLocalTCC(bean);
     }
 
+    @Override
+    public boolean isService(Class<?> beanClass) throws FrameworkException {
+        return isLocalTCC(beanClass);
+    }
+
     @Override
     public RemotingDesc getServiceDesc(Object bean, String beanName) throws 
FrameworkException {
         if (!this.isRemoting(bean, beanName)) {
@@ -84,6 +89,10 @@ public class LocalTCCRemotingParser extends 
AbstractedRemotingParser {
      */
     private boolean isLocalTCC(Object bean) {
         Class<?> classType = bean.getClass();
+        return isLocalTCC(classType);
+    }
+
+    private boolean isLocalTCC(Class<?> classType) {
         Set<Class<?>> interfaceClasses = 
ReflectionUtil.getInterfaces(classType);
         for (Class<?> interClass : interfaceClasses) {
             if (interClass.isAnnotationPresent(LocalTCC.class)) {
diff --git 
a/tcc/src/main/java/io/seata/rm/tcc/resource/parser/TccRegisterResourceParser.java
 
b/tcc/src/main/java/io/seata/rm/tcc/resource/parser/TccRegisterResourceParser.java
index 1918dd2419..c3a4035715 100644
--- 
a/tcc/src/main/java/io/seata/rm/tcc/resource/parser/TccRegisterResourceParser.java
+++ 
b/tcc/src/main/java/io/seata/rm/tcc/resource/parser/TccRegisterResourceParser.java
@@ -16,80 +16,68 @@
  */
 package io.seata.rm.tcc.resource.parser;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
 import io.seata.common.exception.FrameworkException;
 import io.seata.common.util.ReflectionUtil;
 import io.seata.common.util.StringUtils;
 import io.seata.integration.tx.api.interceptor.ActionContextUtil;
-import io.seata.integration.tx.api.interceptor.TxBeanParserUtils;
 import io.seata.integration.tx.api.interceptor.parser.RegisterResourceParser;
-import io.seata.integration.tx.api.remoting.RemotingDesc;
-import io.seata.integration.tx.api.remoting.parser.DefaultRemotingParser;
 import io.seata.rm.DefaultResourceManager;
 import io.seata.rm.tcc.TCCResource;
 import io.seata.rm.tcc.api.BusinessActionContext;
 import io.seata.rm.tcc.api.BusinessActionContextParameter;
 import io.seata.rm.tcc.api.TwoPhaseBusinessAction;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
 /**
  */
 public class TccRegisterResourceParser implements RegisterResourceParser {
 
     @Override
     public void registerResource(Object target, String beanName) {
-        boolean isTxRemotingBean = TxBeanParserUtils.isTxRemotingBean(target, 
beanName);
-        if (isTxRemotingBean) {
-            RemotingDesc remotingDesc = 
DefaultRemotingParser.get().getRemotingBeanDesc(target);
-            if (remotingDesc != null) {
-                if (remotingDesc.isService()) {
-                    try {
-                        //service bean, registry resource
-                        Class<?> serviceClass = remotingDesc.getServiceClass();
-                        Set<Method> methods = new 
HashSet<>(Arrays.asList(serviceClass.getMethods()));
-                        Set<Class<?>> interfaceClasses = 
ReflectionUtil.getInterfaces(serviceClass);
-                        if (interfaceClasses != null) {
-                            for (Class<?> interClass : interfaceClasses) {
-                                
methods.addAll(Arrays.asList(interClass.getMethods()));
-                            }
-                        }
-                        Object targetBean = remotingDesc.getTargetBean();
-                        for (Method m : methods) {
-                            TwoPhaseBusinessAction twoPhaseBusinessAction = 
m.getAnnotation(TwoPhaseBusinessAction.class);
-                            if (twoPhaseBusinessAction != null) {
-                                TCCResource tccResource = new TCCResource();
-                                if 
(StringUtils.isBlank(twoPhaseBusinessAction.name())) {
-                                    throw new FrameworkException("TCC bean 
name cannot be null or empty");
-                                }
-                                
tccResource.setActionName(twoPhaseBusinessAction.name());
-                                tccResource.setTargetBean(targetBean);
-                                tccResource.setPrepareMethod(m);
-                                
tccResource.setCommitMethodName(twoPhaseBusinessAction.commitMethod());
-                                
tccResource.setCommitMethod(serviceClass.getMethod(twoPhaseBusinessAction.commitMethod(),
-                                        
twoPhaseBusinessAction.commitArgsClasses()));
-                                
tccResource.setRollbackMethodName(twoPhaseBusinessAction.rollbackMethod());
-                                
tccResource.setRollbackMethod(serviceClass.getMethod(twoPhaseBusinessAction.rollbackMethod(),
-                                        
twoPhaseBusinessAction.rollbackArgsClasses()));
-                                // set argsClasses
-                                
tccResource.setCommitArgsClasses(twoPhaseBusinessAction.commitArgsClasses());
-                                
tccResource.setRollbackArgsClasses(twoPhaseBusinessAction.rollbackArgsClasses());
-                                // set phase two method's keys
-                                
tccResource.setPhaseTwoCommitKeys(this.getTwoPhaseArgs(tccResource.getCommitMethod(),
-                                        
twoPhaseBusinessAction.commitArgsClasses()));
-                                
tccResource.setPhaseTwoRollbackKeys(this.getTwoPhaseArgs(tccResource.getRollbackMethod(),
-                                        
twoPhaseBusinessAction.rollbackArgsClasses()));
-                                //registry tcc resource
-                                
DefaultResourceManager.get().registerResource(tccResource);
-                            }
-                        }
-                    } catch (Throwable t) {
-                        throw new FrameworkException(t, "parser remoting 
service error");
-                    }
+        try {
+            //service bean, registry resource
+            Class<?> serviceClass = target.getClass();
+            this.executeRegisterResource(target, new 
HashSet<>(Arrays.asList(serviceClass.getMethods())), target.getClass());
+            Set<Class<?>> interfaceClasses = 
ReflectionUtil.getInterfaces(serviceClass);
+            for (Class<?> interClass : interfaceClasses) {
+                this.executeRegisterResource(target, new 
HashSet<>(Arrays.asList(interClass.getMethods())), interClass);
+            }
+        } catch (Throwable t) {
+            throw new FrameworkException(t, "parser remoting service error");
+        }
+    }
+
+    private void executeRegisterResource(Object target, Set<Method> methods, 
Class<?> targetServiceClass) throws NoSuchMethodException {
+        for (Method m : methods) {
+            TwoPhaseBusinessAction twoPhaseBusinessAction = 
m.getAnnotation(TwoPhaseBusinessAction.class);
+            if (twoPhaseBusinessAction != null) {
+                TCCResource tccResource = new TCCResource();
+                if (StringUtils.isBlank(twoPhaseBusinessAction.name())) {
+                    throw new FrameworkException("TCC bean name cannot be null 
or empty");
                 }
+                tccResource.setActionName(twoPhaseBusinessAction.name());
+                tccResource.setTargetBean(target);
+                tccResource.setPrepareMethod(m);
+                
tccResource.setCommitMethodName(twoPhaseBusinessAction.commitMethod());
+                
tccResource.setCommitMethod(targetServiceClass.getMethod(twoPhaseBusinessAction.commitMethod(),
+                        twoPhaseBusinessAction.commitArgsClasses()));
+                
tccResource.setRollbackMethodName(twoPhaseBusinessAction.rollbackMethod());
+                
tccResource.setRollbackMethod(targetServiceClass.getMethod(twoPhaseBusinessAction.rollbackMethod(),
+                        twoPhaseBusinessAction.rollbackArgsClasses()));
+                // set argsClasses
+                
tccResource.setCommitArgsClasses(twoPhaseBusinessAction.commitArgsClasses());
+                
tccResource.setRollbackArgsClasses(twoPhaseBusinessAction.rollbackArgsClasses());
+                // set phase two method's keys
+                
tccResource.setPhaseTwoCommitKeys(this.getTwoPhaseArgs(tccResource.getCommitMethod(),
+                        twoPhaseBusinessAction.commitArgsClasses()));
+                
tccResource.setPhaseTwoRollbackKeys(this.getTwoPhaseArgs(tccResource.getRollbackMethod(),
+                        twoPhaseBusinessAction.rollbackArgsClasses()));
+                //registry tcc resource
+                DefaultResourceManager.get().registerResource(tccResource);
             }
         }
     }


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscr...@seata.apache.org
For additional commands, e-mail: notifications-h...@seata.apache.org

Reply via email to