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容易包冲突

  • 相关阅读:
    记录
    Excel 中显示html 数字格式的问题。
    oracle 获取 报错的问题在第几行 Dbms_Utility.Format_Error_Backtrace
    C#9.0新特性详解系列之六:增强的模式匹配
    C# 9.0新特性详解系列之五:记录(record)和with表达式
    C#9.0新特性详解系列之四:顶级程序语句(Top-Level Programs)
    C# 9.0新特性详解系列之三:模块初始化器
    C# 9.0新特性详解系列之二:扩展方法GetEnumerator支持foreach循环
    C# 9.0新特性详解系列之一:只初始化设置器(init only setter)
    C# 9.0 正式版所有新特性概述(最新完善版)
  • 原文地址:https://www.cnblogs.com/silyvin/p/13778331.html
Copyright © 2011-2022 走看看