1 用spring托管对象调用原生带有自定义注解的方法
GsztbLiveService service = ContextHelper.getBean(GsztbLiveService.class); // service.getClass().getDeclaredMethods(); Method[] methods = GsztbLiveService.class.getDeclaredMethods(); for (Method method : methods) { SocketDefault an = method.getAnnotation(SocketDefault.class); if (null != an) { Object object = null; try { object = method.invoke(service); } catch (Exception e) { e.printStackTrace(); }
cglib生成子类注入spring,改写方法后遗失了注解,注解的继承,注解无法被改写的方法继承
请注意,这不是个继承的问题,这是cglib从无到有生成子类,过程中,没保留父类方法上的注解 jdk动态代理与cglib优势劣势以及jdk动态代理为什么要interface (二) 第4点
2 jdk动态代理work log 2020.4.28
public class TransactionProxyFactory implements InvocationHandler { private Object target; public TransactionProxyFactory(Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { SCEF_DB_TRANSACTIONAL scef_db_transactional = method.getAnnotation(SCEF_DB_TRANSACTIONAL.class); if(scef_db_transactional != null) {
Orm2Service orm2Service = new Orm2ServiceImpl();
Orm2Service proxy = (Orm2Service) new TransactionProxyFactory(orm2Service).getProxyInstance();
proxy.xxxx();
自定义注解必须在接口上,在实现类上的无效
根本原因:动态代理和cglib,会丢掉被代理类成员变量和方法上的注解
具体可根据jdk动态代理源码底层(jdk生成字节码及5种字节码生产方式比较)思考
public final class $Proxy0 extends Proxy implements IUserDao { private static Method m1; private static Method m3;
public final void save() throws {【我们的方法】 try { super.h.invoke(this, m3, (Object[])null); } catch (RuntimeException | Error var2) { throw var2; } catch (Throwable var3) { throw new UndeclaredThrowableException(var3); } }
可以看到,这里传入TransactionProxyFactory.invoke的Method m3,是jdk动态代理增强类$Proxy0的静态成员变量,它是从接口直接interface.class.getMethods拿来的的,自然也带有Annotation,一起传入invoke被我们捕捉
3 cglib
cglib生成被代理class子类,可以应用inherited元注解
然而:根据注解的本质(yet) ,元注解Inherited声明出的注解,在使用时用在类上,可以被子类所继承,对属性或方法无效
纠正:注解的继承
猜测cglib在切面的时候,通过代理类.class.getFather找到被代理类,然后继而找到@Transaction修饰的方法
4 坑