当自定义注解遇到spring和类增强
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 坑




浙公网安备 33010602011771号