标签: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