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:fix wrong proxy of datasource bean #2323

Merged
merged 30 commits into from
Mar 25, 2020
Merged
Changes from 3 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9a795a3
fix duplicate proxy of bean.
xingfudeshi Feb 28, 2020
99e4f38
Update SeataDataSourceBeanPostProcessor.java
xingfudeshi Feb 28, 2020
7bda414
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Feb 28, 2020
881550c
Merge branch 'develop' into fix_duplicate_proxy
zjinlei Mar 4, 2020
75f8b4a
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 4, 2020
e31f5a6
fix review
xingfudeshi Mar 6, 2020
31edb8c
Merge branch 'fix_duplicate_proxy' of https://github.com/xingfudeshi/…
xingfudeshi Mar 6, 2020
85b270c
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 6, 2020
fc28853
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 9, 2020
5fd3fd4
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 11, 2020
823fb41
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 13, 2020
20473c3
implements PriorityOrdered
xingfudeshi Mar 13, 2020
01a16aa
use Ordered instead of PriorityOrdered
xingfudeshi Mar 13, 2020
a9a844e
using spring to create automatic proxy
xingfudeshi Mar 15, 2020
7ab6b3c
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 15, 2020
ae3d756
using spring to create automatic proxy
xingfudeshi Mar 15, 2020
9672d29
add exclude
xingfudeshi Mar 15, 2020
7c20a07
Merge branch 'develop' into fix_duplicate_proxy
zjinlei Mar 15, 2020
5abe6a8
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 17, 2020
b4c2774
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 19, 2020
acdbdfc
use Spring AOP to create auto-proxy
xingfudeshi Mar 19, 2020
8f239ad
Merge remote-tracking branch 'origin/fix_duplicate_proxy' into fix_du…
xingfudeshi Mar 19, 2020
8e915d0
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 19, 2020
c46c6d6
remove wrapIfNecessary
xingfudeshi Mar 20, 2020
798cbb2
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 20, 2020
98be2f0
Merge branch 'fix_duplicate_proxy' of https://github.com/xingfudeshi/…
xingfudeshi Mar 20, 2020
5475cbb
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 21, 2020
2a5f4fb
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 23, 2020
8d3b2c4
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 23, 2020
a849978
Merge branch 'develop' into fix_duplicate_proxy
xingfudeshi Mar 24, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@
package io.seata.spring.annotation.datasource;

import javax.sql.DataSource;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.stream.Stream;

import io.seata.common.exception.ShouldNeverHappenException;
import io.seata.rm.datasource.DataSourceProxy;
Expand All @@ -27,9 +29,11 @@
import net.sf.cglib.proxy.MethodInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.util.ClassUtils;

/**
* @author xingfudeshi@gmail.com
Expand All @@ -45,11 +49,15 @@ public SeataDataSourceBeanPostProcessor(boolean useJdkProxy) {

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof DataSource && !(bean instanceof DataSourceProxy)) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Auto proxy of [{}]", beanName);
try {
if (bean instanceof DataSource && !isAutoProxiedBySeata(bean)) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Auto proxy of [{}]", beanName);
}
return proxyDataSource(bean);
}
return proxyDataSource(bean);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return bean;
}
Expand Down Expand Up @@ -105,4 +113,62 @@ private Object handleMethodProxy(DataSourceProxy dataSourceProxy, Method method,
}
}
}

/**
* is auto proxied by seata
*
* @param bean
* @return true, if this bean has been auto-proxied by seata
*/
private boolean isAutoProxiedBySeata(Object bean) throws NoSuchFieldException, IllegalAccessException {
if (bean instanceof DataSourceProxy) {
return true;
}
//handle Spring AOP
Object proxyTargetObject = bean;
if (AopUtils.isAopProxy(proxyTargetObject)) {
try {
proxyTargetObject = SpringProxyUtils.getAdvisedSupport(bean).getTargetSource().getTarget();
slievrly marked this conversation as resolved.
Show resolved Hide resolved
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Field field = null;
//handle Normal proxy object
if (ClassUtils.isCglibProxy(proxyTargetObject)) {
//CGLIB Proxy
field = proxyTargetObject.getClass().getDeclaredField("CGLIB$CALLBACK_0");
} else if (Proxy.isProxyClass(proxyTargetObject.getClass())) {
//JDK Proxy
field = proxyTargetObject.getClass().getDeclaredField("h");
xingfudeshi marked this conversation as resolved.
Show resolved Hide resolved
}
return doCheckAutoProxy(field, proxyTargetObject);
}

/**
* do check auto proxy
*
* @param field
* @param proxiedObject
* @return
* @throws IllegalAccessException
*/
private boolean doCheckAutoProxy(Field field, Object proxiedObject) throws IllegalAccessException {
if (null == field) {
return false;
}
field.setAccessible(true);
xingfudeshi marked this conversation as resolved.
Show resolved Hide resolved
Object fieldObject = field.get(proxiedObject);
return Stream.of(fieldObject.getClass().getDeclaredFields()).anyMatch(f -> {
f.setAccessible(true);
Object targetObject;
try {
targetObject = f.get(fieldObject);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return targetObject instanceof DataSourceProxy;
xingfudeshi marked this conversation as resolved.
Show resolved Hide resolved
});
}

}