当动态代理遇到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容易包冲突

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