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