Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix: can't integrate dubbo with spring #6015

Merged
merged 17 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changes/en-us/2.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ The version is updated as follows:
- [[#5887](https://github.com/seata/seata/pull/5887)] fix global transaction hook repeat execute
- [[#6018](https://github.com/seata/seata/pull/6018)] fix incorrect metric report
- [[#6024](https://github.com/seata/seata/pull/6024)] fix the white screen after click the "View Global Lock" button on the transaction info page in the console
- [[#6015](https://github.com/seata/seata/pull/6015)] fix can't integrate dubbo with spring

### optimize:
- [[#5966](https://github.com/seata/seata/pull/5966)] decouple saga expression handling and remove evaluator package
Expand Down Expand Up @@ -219,6 +220,7 @@ Thanks to these contributors for their code commits. Please report an unintended
- [Aruato](https://github.com/Aruato)
- [ptyin](https://github.com/ptyin)
- [jsbxyyx](https://github.com/jsbxyyx)
- [xxxcrel](https://github.com/xxxcrel)


Also, we receive many valuable issues, questions and advices from our community. Thanks for you all.
Expand Down
2 changes: 2 additions & 0 deletions changes/zh-cn/2.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单
- [[#5887](https://github.com/seata/seata/pull/5887)] 修复全局事务钩子重复执行
- [[#6018](https://github.com/seata/seata/pull/6018)] 修复错误的 metric 上报
- [[#6024](https://github.com/seata/seata/pull/6024)] 修复控制台点击事务信息页面中的"查看全局锁"按钮之后白屏的问题
- [[#6015](https://github.com/seata/seata/pull/6015)] 修复在spring环境下无法集成dubbo


### optimize:
Expand Down Expand Up @@ -221,6 +222,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单
- [ggbocoder](https://github.com/ggbocoder)
- [ptyin](https://github.com/ptyin)
- [jsbxyyx](https://github.com/jsbxyyx)
- [xxxcrel](https://github.com/xxxcrel)



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ protected void initInterfaceParser() {
}

@Override
public ProxyInvocationHandler parserInterfaceToProxy(Object target) throws Exception {
public ProxyInvocationHandler parserInterfaceToProxy(Object target, String beanName) throws Exception {
for (InterfaceParser interfaceParser : ALL_INTERFACE_PARSERS) {
ProxyInvocationHandler proxyInvocationHandler = interfaceParser.parserInterfaceToProxy(target);
ProxyInvocationHandler proxyInvocationHandler = interfaceParser.parserInterfaceToProxy(target, beanName);
if (proxyInvocationHandler != null) {
return proxyInvocationHandler;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public class DefaultResourceRegisterParser {

protected static List<RegisterResourceParser> allRegisterResourceParsers = new ArrayList<>();

public void registerResource(Object target) {
public void registerResource(Object target, String beanName) {
for (RegisterResourceParser registerResourceParser : allRegisterResourceParsers) {
registerResourceParser.registerResource(target);
registerResourceParser.registerResource(target, beanName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public class GlobalTransactionalInterceptorParser implements InterfaceParser {
* @see GlobalLock // GlobalLock annotation
*/
@Override
public ProxyInvocationHandler parserInterfaceToProxy(Object target) throws Exception {
public ProxyInvocationHandler parserInterfaceToProxy(Object target, String beanName) throws Exception {
Class<?> serviceInterface = DefaultTargetClassParser.get().findTargetClass(target);
Class<?>[] interfacesIfJdk = DefaultTargetClassParser.get().findInterfaces(target);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*/
public interface InterfaceParser {

ProxyInvocationHandler parserInterfaceToProxy(Object target) throws Exception;
ProxyInvocationHandler parserInterfaceToProxy(Object target, String beanName) throws Exception;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2.x 目前和spring解耦的,beanName是spring的定义。我们这里设置成objectName是不是更好,在spring的场景下:objectName = beanName

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done



}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
*/
public interface RegisterResourceParser {

void registerResource(Object target);
void registerResource(Object target, String beanName);

}
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ protected void initRemotingParser() {
}
}

/**
* register custom remoting parser
* @param remotingParser
*/
public void registerRemotingParser(RemotingParser remotingParser) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

注册方法最好加锁(因为可以牵扯到并发注册),或者使用copyOnwrite的方式

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

allRemotingParsers.add(remotingParser);
}
/**
* is remoting bean ?
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ public class ProxyUtil {
private static final Map<Object, Object> PROXYED_SET = new HashMap<>();

public static <T> T createProxy(T target) {
return createProxy(target, target.getClass().getName());
}

public static <T> T createProxy(T target, String beanName) {
try {
synchronized (PROXYED_SET) {
if (PROXYED_SET.containsKey(target)) {
return (T) PROXYED_SET.get(target);
}
ProxyInvocationHandler proxyInvocationHandler = DefaultInterfaceParser.get().parserInterfaceToProxy(target);
ProxyInvocationHandler proxyInvocationHandler = DefaultInterfaceParser.get().parserInterfaceToProxy(target, beanName);
if (proxyInvocationHandler == null) {
return target;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void parserInterfaceToProxy() throws Exception {
GlobalTransactionalInterceptorParser globalTransactionalInterceptorParser = new GlobalTransactionalInterceptorParser();

//when
ProxyInvocationHandler proxyInvocationHandler = globalTransactionalInterceptorParser.parserInterfaceToProxy(business);
ProxyInvocationHandler proxyInvocationHandler = globalTransactionalInterceptorParser.parserInterfaceToProxy(business, business.getClass().getName());

//then
Assertions.assertNotNull(proxyInvocationHandler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,10 @@
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.remoting.parser.DefaultRemotingParser;
import io.seata.rm.RMClient;
import io.seata.spring.annotation.scannercheckers.PackageScannerChecker;
import io.seata.spring.remoting.parser.RemotingFactoryBeanParser;
import io.seata.spring.util.OrderUtil;
import io.seata.spring.util.SpringProxyUtils;
import io.seata.tm.TMClient;
Expand Down Expand Up @@ -279,7 +281,7 @@ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey)
return bean;
}
interceptor = null;
ProxyInvocationHandler proxyInvocationHandler = DefaultInterfaceParser.get().parserInterfaceToProxy(bean);
ProxyInvocationHandler proxyInvocationHandler = DefaultInterfaceParser.get().parserInterfaceToProxy(bean, beanName);
if (proxyInvocationHandler == null) {
return bean;
}
Expand Down Expand Up @@ -472,6 +474,8 @@ public void afterPropertiesSet() {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
RemotingFactoryBeanParser remotingFactoryBeanParser = new RemotingFactoryBeanParser(applicationContext);
DefaultRemotingParser.get().registerRemotingParser(remotingFactoryBeanParser);
this.setBeanFactory(applicationContext);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@
*/
public class RemotingFactoryBeanParser extends AbstractedRemotingParser {

public static ApplicationContext applicationContext;
public ApplicationContext applicationContext;

public RemotingFactoryBeanParser(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}

/**
* if it is proxy bean, check if the FactoryBean is Remoting bean
Expand All @@ -36,7 +40,7 @@ public class RemotingFactoryBeanParser extends AbstractedRemotingParser {
* @param beanName the bean name
* @return boolean boolean
*/
protected static Object getRemotingFactoryBean(Object bean, String beanName) {
protected Object getRemotingFactoryBean(Object bean, String beanName) {
Copy link
Contributor

@wt-better wt-better Nov 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

我们是不是在构造方法里面加一个applicationContext!=null的check(防止一些spring异常场景,applicationContext没set进去),那么getRemotingFactoryBean里面的applicationContext!=null是可以去除掉的。

另外factoryBeanName的构建落在多个方法里面,是否能够抽出一个统一的方法

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

if (!SpringProxyUtils.isProxy(bean)) {
return null;
}
Expand All @@ -55,7 +59,8 @@ public boolean isReference(Object bean, String beanName) {
if (factoryBean == null) {
return false;
}
return DefaultRemotingParser.get().isReference(bean, beanName);
String factoryBeanName = "&" + beanName;
return DefaultRemotingParser.get().isReference(factoryBean, factoryBeanName);
}

@Override
Expand All @@ -64,7 +69,8 @@ public boolean isService(Object bean, String beanName) {
if (factoryBean == null) {
return false;
}
return DefaultRemotingParser.get().isReference(bean, beanName);
String factoryBeanName = "&" + beanName;
return DefaultRemotingParser.get().isService(factoryBean, factoryBeanName);
}

@Override
Expand All @@ -73,12 +79,13 @@ public RemotingDesc getServiceDesc(Object bean, String beanName) throws Framewor
if (factoryBean == null) {
return null;
}
return DefaultRemotingParser.get().getServiceDesc(bean, beanName);
String factoryBeanName = "&" + beanName;
return DefaultRemotingParser.get().getServiceDesc(factoryBean, factoryBeanName);
}


@Override
public short getProtocol() {
return 0;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public void addTccAdvise(Object bean, String beanName, Field field, Class servic
RemotingDesc remotingDesc = new RemotingDesc();
remotingDesc.setServiceClass(serviceClass);

Object proxyBean = ProxyUtil.createProxy(bean);
Object proxyBean = ProxyUtil.createProxy(bean, beanName);
field.setAccessible(true);
field.set(bean, proxyBean);
LOGGER.info("Bean[" + bean.getClass().getName() + "] with name [" + field.getName() + "] would use proxy");
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@
public class TccActionInterceptorParser implements InterfaceParser {

@Override
public ProxyInvocationHandler parserInterfaceToProxy(Object target) {
boolean isTxRemotingBean = TxBeanParserUtils.isTxRemotingBean(target, target.toString());
public ProxyInvocationHandler parserInterfaceToProxy(Object target, String beanName) {
boolean isTxRemotingBean = TxBeanParserUtils.isTxRemotingBean(target, beanName);
if (isTxRemotingBean) {
RemotingDesc remotingDesc = DefaultRemotingParser.get().getRemotingBeanDesc(target);
if (remotingDesc != null) {
if (remotingDesc.isService()) {
DefaultResourceRegisterParser.get().registerResource(target);
DefaultResourceRegisterParser.get().registerResource(target, beanName);
}
if (remotingDesc.isReference()) {
//if it is a tcc remote reference
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
public class TccRegisterResourceParser implements RegisterResourceParser {

@Override
public void registerResource(Object target) {
boolean isTxRemotingBean = TxBeanParserUtils.isTxRemotingBean(target, target.toString());
public void registerResource(Object target, String beanName) {
boolean isTxRemotingBean = TxBeanParserUtils.isTxRemotingBean(target, beanName);
if (isTxRemotingBean) {
RemotingDesc remotingDesc = DefaultRemotingParser.get().getRemotingBeanDesc(target);
if (remotingDesc != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ void parserInterfaceToProxy() {
NormalTccActionImpl tccAction = new NormalTccActionImpl();

//when
ProxyInvocationHandler proxyInvocationHandler = tccActionInterceptorParser.parserInterfaceToProxy(tccAction);
ProxyInvocationHandler proxyInvocationHandler = tccActionInterceptorParser.parserInterfaceToProxy(tccAction, tccAction.getClass().getName());

//then
Assertions.assertNotNull(proxyInvocationHandler);
Expand Down
Loading