zoukankan      html  css  js  c++  java
  • 当动态代理遇到ioc (二)cglib

    mybatis guice 事务代理切面的代码:

    package sun.myproxy;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    /**
     * https://www.cnblogs.com/silyvin/p/13778331.html
     * Created by joyce on 2020/10/7.
     */
    public class OdsTransactionCglibFactory extends OdsTransactionProxyFactory implements MethodInterceptor {
    
        public OdsTransactionCglibFactory(Object target) {
            super(target);
        }
    
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    
            IOC();
    
            MY_TRANSACTIONAL scef_db_transactional = method.getAnnotation(MY_TRANSACTIONAL.class);

    // 迎合有些人习惯将注解加到接口上 Class[] interfaces = target.getClass().getInterfaces(); if(scef_db_transactional == null) { for(Class inter : interfaces) { Method classMethod = inter.getMethod(method.getName(), method.getParameterTypes()); scef_db_transactional = classMethod.getAnnotation(MY_TRANSACTIONAL.class); break; } } // MyServiceImpl.method { Method classMethod = method; System.out.println(classMethod); MY_TRANSACTIONAL my_transactional = classMethod.getAnnotation(MY_TRANSACTIONAL.class); System.out.println(my_transactional); } // MyServiceImpl&&CGLIB.method { Method classMethod = o.getClass().getMethod(method.getName(), method.getParameterTypes()); System.out.println(classMethod); MY_TRANSACTIONAL my_transactional = classMethod.getAnnotation(MY_TRANSACTIONAL.class); System.out.println(my_transactional); } // MyService.method { Method classMethod = interfaces[0].getMethod(method.getName(), method.getParameterTypes()); System.out.println(classMethod); MY_TRANSACTIONAL my_transactional = classMethod.getAnnotation(MY_TRANSACTIONAL.class); System.out.println(my_transactional); } if(scef_db_transactional != null) { return invokeHasTransactional(scef_db_transactional, method, args); } else { return invokeNoTransactional(method, args); } } @Override public Object getProxyInstance(){ Enhancer en = new Enhancer(); en.setSuperclass(target.getClass()); en.setCallback(this); Object oCglib = en.create(); return oCglib; } }

    public void sun.myproxybean.MyServiceImpl.multi()
    @sun.myproxy.MY_TRANSACTIONAL()
    public final void sun.myproxybean.MyServiceImpl$$EnhancerByCGLIB$$5b3ba48d.multi()
    null
    public abstract void sun.myproxybean.MyService.multi()
    null

    以下为 当动态代理遇到ioc (四)真正的cglib 第5点补充控制台日志:

    public void sun.myproxybean.MyDaoImpl.multi()
    @sun.myproxy.MY_TRANSACTIONAL()
    public final void sun.myproxybean.MyDaoImpl$$EnhancerByCGLIB$$4b5f7f6c.multi()
    null
    public abstract void sun.myproxybean.MyDao.multi()
    null

    结论:

    1 cglib生成子类时,不保留父类方法注解

    2 由于注入的是cglib proxy,而@Autowired项对象在原始类,其父类上,而其父类原始对象没有被ioc,故仍需要手动反哺

    3 asm cglib容易包冲突

  • 相关阅读:
    hbase二级索引学习
    redis-cluster集群Mac部署
    http-flume-kafka.conf
    linux 替换文件中的字符串
    flumeDemo
    redis_exporter监控安装
    Hbase内存磁盘大致关系
    spring cloud 尚硅谷学习
    C10K问题
    navicat 远程链接Mysql问题
  • 原文地址:https://www.cnblogs.com/silyvin/p/13778331.html
Copyright © 2011-2022 走看看