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