public Object afterMethod()

in apm-sniffer/apm-sdk-plugin/spring-plugins/core-patch/src/main/java/org/apache/skywalking/apm/plugin/spring/patch/AutowiredAnnotationProcessorInterceptor.java [45:96]


    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        Object ret) throws Throwable {
        Class<?> beanClass = (Class<?>) allArguments[0];
        if (EnhancedInstance.class.isAssignableFrom(beanClass)) {
            Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = (Map<Class<?>, Constructor<?>[]>) objInst.getSkyWalkingDynamicField();

            Constructor<?>[] candidateConstructors = candidateConstructorsCache.get(beanClass);
            if (candidateConstructors == null) {
                Constructor<?>[] returnCandidateConstructors = (Constructor<?>[]) ret;

                /**
                 * The return for the method {@link org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors(Class, String)
                 * contains three cases:
                 * 1. Constructors with annotation {@link org.springframework.beans.factory.annotation.Autowired}.
                 * 2. The bean class only has one constructor with parameters.
                 * 3. The bean has constructor without parameters.
                 *
                 * because of the manipulate mechanism generates another private constructor in the enhance class, all the class that constrcutor enhance by skywalking
                 * cannot go to case two, and it will go to case three. case one is not affected in the current manipulate mechanism situation.
                 *
                 * The interceptor fill out the private constructor when the class is enhanced by skywalking, and check if the remainder constructors size is equals one,
                 * if yes, return the constructor. or return constructor without parameters.
                 *
                 * @see org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors(Class, String)
                 */
                if (returnCandidateConstructors == null) {
                    Constructor<?>[] rawConstructor = beanClass.getDeclaredConstructors();
                    List<Constructor<?>> candidateRawConstructors = new ArrayList<Constructor<?>>();
                    for (Constructor<?> constructor : rawConstructor) {
                        if (!constructor.isSynthetic()) {
                            candidateRawConstructors.add(constructor);
                        }
                    }

                    if (candidateRawConstructors.size() == 1 && candidateRawConstructors.get(0)
                                                                                        .getParameterTypes().length > 0) {
                        candidateConstructors = new Constructor<?>[] {candidateRawConstructors.get(0)};
                    } else {
                        candidateConstructors = new Constructor<?>[0];
                    }

                } else {
                    candidateConstructors = returnCandidateConstructors;
                }

                candidateConstructorsCache.put(beanClass, candidateConstructors);
            }

            return candidateConstructors.length > 0 ? candidateConstructors : null;
        }
        return ret;
    }