标签:field ann www tran bsp forms stat exception get
在 work log 2020.4.28中,我们使用jdk动态代理处理方法的事务增强
图1 问题的引出
1 起先,我们禁止被增强的类里面使用注解注入依赖,代码会自动审核这种情况
private static final class TransactionProxyProvider<T> implements Provider<T> {
private Object target;
public TransactionProxyProvider(Object target) {
this.target = target;
}
@Override
public T get() {
try {
// Class cl = target.getClass();
// Field [] fields = cl.getDeclaredFields();
// for(Field field : fields) {
// field.setAccessible(true);
// if(field.isAnnotationPresent(Inject.class))
// throw new RuntimeException("proxy class do not allow com.google.inject annotation - " + cl.getName());
// }
return (T)new TransactionProxyFactory(target).getProxyInstance();
} catch (Exception e) {
loggerCommon.error(e.getMessage(), e);
}
return null;
}
}
图2 解决方案
public class TransactionProxyFactory implements InvocationHandler {
private volatile boolean hasNotInjected = true;
private Object target;
public TransactionProxyFactory(Object target){
this.target = target;
}
private <T> T getBeanFromFactoryGuice(Class<T> c) {
Injector injector = CRFGuiceContext.getInjector();
return injector.getInstance(c);
}
private Class getBeanInjectAnnotationGuice() {
return com.google.inject.Inject.class;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(hasNotInjected) {
synchronized (this) {
if(hasNotInjected) {
Class clProxy = target.getClass();
Field [] fields = clProxy.getDeclaredFields();
for(Field field : fields) {
field.setAccessible(true);
if(!field.isAnnotationPresent(getBeanInjectAnnotationGuice()))
continue;
String name = field.getName();
Class fieldType = field.getType();
Object obj = getBeanFromFactoryGuice(fieldType);
if(obj != null)
field.set(target, obj);
}
hasNotInjected = false;
}
}
}
SCEF_DB_TRANSACTIONAL scef_db_transactional = method.getAnnotation(SCEF_DB_TRANSACTIONAL.class);
if(scef_db_transactional != null) {
ScefOrmSession scefOrmSession = getBeanFromFactoryGuice(ScefOrmSession.class);
Boolean readOnly = scef_db_transactional.readOnly();
int isolation = scef_db_transactional.isolation();
try {
scefOrmSession.startTransaction(readOnly, isolation);
Object returnValue = method.invoke(target, args);
scefOrmSession.commit();
return returnValue;
} catch (InvocationTargetException ie) {
Throwable throwable = ie.getTargetException();
Class c1 = throwable.getClass();
Class [] c2 = scef_db_transactional.noRollbackFor();
int sum = 0;
for(Class c : c2) {
if(c.equals(c1))
sum ++ ;
}
if(sum == 0)
scefOrmSession.rollback();
else
scefOrmSession.commit();
throw new DBException(throwable);
} catch (Exception e) {
throw new DBException(e);
} finally {
scefOrmSession.endTransaction();
}
} else {
Object returnValue = method.invoke(target, args);
return returnValue;
}
}
public Object getProxyInstance(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
}
标签:field ann www tran bsp forms stat exception get
原文地址:https://www.cnblogs.com/silyvin/p/12803333.html