码迷,mamicode.com
首页 > 其他好文 > 详细

当动态代理遇到ioc

时间:2020-04-29 18:58:40      阅读:78      评论:0      收藏:0      [点我收藏+]

标签: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);
    }
}

  

当动态代理遇到ioc

标签:field   ann   www   tran   bsp   forms   stat   exception   get   

原文地址:https://www.cnblogs.com/silyvin/p/12803333.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!