cglib dynamic proxy causes annotation loss and how to modify annotation to allow inheritance

phenomenon

SOAService is a bean that passes through two beanpostprocessors one after the other. You will find that the annotation is lost after the proxy.

  

    

cglib agent enabled

@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class Application {
    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Application.class);
        app.run(args);
    }
}

Why open this agent mode

  http://www.cnblogs.com/hujunzheng/p/8428422.html 

How to solve this problem

Add @ Inherited to the custom annotation. If it is a third-party annotation, adjust the project interface layer or take this annotation and add @ Inherited annotation through code, or as shown in the figure below.

  

 

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    Service anon = bean.getClass().getAnnotation(Service.class);
    if (anon != null) {
        try {
            InvocationHandler h = Proxy.getInvocationHandler(anon);

            //Set up@Service Annotation supports inheritance, and it should deal with the problem that dynamic proxy causes@Service Missing annotation
            Field typeField = h.getClass().getDeclaredField("type");
            typeField.setAccessible(true);
            Field annotationTypeField = Class.class.getDeclaredField("annotationType");
            annotationTypeField.setAccessible(true);
            AnnotationType annotationType = (AnnotationType) annotationTypeField.get(typeField.get(h));
            Field inheritedField = AnnotationType.class.getDeclaredField("inherited");
            this.updateFinalModifiers(inheritedField);
            inheritedField.set(annotationType, true);

            // Obtain AnnotationInvocationHandler Of memberValues field
            Field memberValuesField = h.getClass().getDeclaredField("memberValues");
            // Because of this field private final Decorate, so open permissions
            memberValuesField.setAccessible(true);
            // Obtain memberValues
            Map memberValues = (Map) memberValuesField.get(h);

            Service service = Stream.of(bean.getClass().getInterfaces())
                    .filter(iface -> iface.getAnnotation(Service.class) != null)
                    .collect(Collectors.toList())
                    .get(0)
                    .getAnnotation(Service.class);

            memberValues.put("version", service.version());
            memberValues.put("group", service.group());
        } catch (Exception e) {
            throw new BeanCreationException(String.format("%s %s %s %s %s"
                        , "modify"
                        , ClassUtils.getQualifiedName(bean.getClass())
                        , "Notes on"
                        , ClassUtils.getQualifiedName(Service.class)
                        , "Of group Value sum version Value error")
                    , e);
        }
    }
    return bean;
}

 

Reference link: Annotation and dynamic proxy

Posted by makeITfunctional on Sun, 26 Apr 2020 08:04:46 -0700