org.springframework.beans.factory.annotation.InjectionMetadata#InjectedElement ( )源码实例Demo

下面列出了org.springframework.beans.factory.annotation.InjectionMetadata#InjectedElement ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

/**
 * Get injected-object from specified {@link AnnotationAttributes annotation attributes} and Bean Class
 *
 * @param attributes      {@link AnnotationAttributes the annotation attributes}
 * @param bean            Current bean that will be injected
 * @param beanName        Current bean name that will be injected
 * @param injectedType    the type of injected-object
 * @param injectedElement {@link InjectionMetadata.InjectedElement}
 * @return An injected object
 * @throws Exception If getting is failed
 */
protected Object getInjectedObject(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
                                   InjectionMetadata.InjectedElement injectedElement) throws Exception {

    String cacheKey = buildInjectedObjectCacheKey(attributes, bean, beanName, injectedType, injectedElement);

    Object injectedObject = injectedObjectsCache.get(cacheKey);

    if (injectedObject == null) {
        injectedObject = doGetInjectedBean(attributes, bean, beanName, injectedType, injectedElement);
        // Customized inject-object if necessary
        injectedObjectsCache.putIfAbsent(cacheKey, injectedObject);
    }

    return injectedObject;

}
 
/**
 * To parse all field to find out annotation info.
 *
 * @param clazz target class
 * @param annotations the annotations
 * @param elements injected element of all fields
 */
protected void parseFields(final Class<?> clazz, final List<Class<? extends Annotation>> annotations,
        final LinkedList<InjectionMetadata.InjectedElement> elements) {
    ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
        public void doWith(Field field) {
            for (Class<? extends Annotation> anno : annotations) {
                Annotation annotation = field.getAnnotation(anno);
                if (annotation != null) {
                    if (Modifier.isStatic(field.getModifiers())) {
                        throw new IllegalStateException("Autowired annotation is not supported on static fields");
                    }
                    elements.add(new AutowiredFieldElement(field, annotation));
                }
            }
        }
    });
}
 
@Override
protected String buildInjectedObjectCacheKey(Reference reference, Object bean, String beanName,
                                             Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) {

    String key = buildReferencedBeanName(reference, injectedType) +
            "#source=" + (injectedElement.getMember()) +
            "#attributes=" + AnnotationUtils.getAttributes(reference,getEnvironment(),true);

    return key;
}
 
@Override
protected Object doGetInjectedBean(NacosInjected annotation, Object bean,
		String beanName, Class<?> injectedType,
		InjectionMetadata.InjectedElement injectedElement) {

	AbstractNacosServiceBeanBuilder serviceBeanBuilder = nacosServiceBeanBuilderMap
			.get(injectedType);

	return serviceBeanBuilder.build(annotation.properties());

}
 
@Override
protected String buildInjectedObjectCacheKey(AnnotationAttributes attributes, Object bean, String beanName,
                                             Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) {
    return injectedType.getName();
}
 
@Override
    protected Object doGetInjectedBean(Reference reference, Object bean, String beanName, Class<?> injectedType,
                                       InjectionMetadata.InjectedElement injectedElement) throws Exception {

//        引用的bean的名字也是指定接口的权限定名=》
        String referencedBeanName = buildReferencedBeanName(reference, injectedType);

        ReferenceBean referenceBean = buildReferenceBeanIfAbsent(referencedBeanName, reference, injectedType, getClassLoader());

        cacheInjectedReferenceBean(referenceBean, injectedElement);

//        返回代理对象
        Object proxy = buildProxy(referencedBeanName, referenceBean, injectedType);

        return proxy;
    }
 
private InjectionMetadata buildPersistenceMetadata(final Class<?> clazz) {
	LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
	Class<?> targetClass = clazz;

	do {
		final LinkedList<InjectionMetadata.InjectedElement> currElements =
				new LinkedList<InjectionMetadata.InjectedElement>();

		ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
			@Override
			public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
				if (field.isAnnotationPresent(PersistenceContext.class) ||
						field.isAnnotationPresent(PersistenceUnit.class)) {
					if (Modifier.isStatic(field.getModifiers())) {
						throw new IllegalStateException("Persistence annotations are not supported on static fields");
					}
					currElements.add(new PersistenceElement(field, field, null));
				}
			}
		});

		ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
			@Override
			public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
				Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
				if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
					return;
				}
				if ((bridgedMethod.isAnnotationPresent(PersistenceContext.class) ||
						bridgedMethod.isAnnotationPresent(PersistenceUnit.class)) &&
						method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
					if (Modifier.isStatic(method.getModifiers())) {
						throw new IllegalStateException("Persistence annotations are not supported on static methods");
					}
					if (method.getParameterTypes().length != 1) {
						throw new IllegalStateException("Persistence annotation requires a single-arg method: " + method);
					}
					PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
					currElements.add(new PersistenceElement(method, bridgedMethod, pd));
				}
			}
		});

		elements.addAll(0, currElements);
		targetClass = targetClass.getSuperclass();
	}
	while (targetClass != null && targetClass != Object.class);

	return new InjectionMetadata(clazz, elements);
}
 
@Override
protected Object doGetInjectedBean(Referenced annotation, Object bean, String beanName, Class<?> injectedType,
                                   InjectionMetadata.InjectedElement injectedElement) throws Exception {
    return getBeanFactory().getBean(injectedType);
}
 
/**
 * Get {@link Map} in injected method.
 *
 * @return non-null {@link Map}
 */
protected Map<InjectionMetadata.InjectedElement, Object> getInjectedMethodObjectsMap() {

    Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
            new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();

    for (AbstractAnnotationBeanPostProcessor.AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {

        Collection<AbstractAnnotationBeanPostProcessor.AnnotatedMethodElement> methodElements = metadata.getMethodElements();

        for (AbstractAnnotationBeanPostProcessor.AnnotatedMethodElement methodElement : methodElements) {

            injectedElementBeanMap.put(methodElement, methodElement.object);

        }

    }

    return Collections.unmodifiableMap(injectedElementBeanMap);

}
 
@Override
protected String buildInjectedObjectCacheKey(Referenced annotation, Object bean, String beanName,
                                             Class<?> injectedType,
                                             InjectionMetadata.InjectedElement injectedElement) {
    return injectedType.getName();
}
 
public InjectionMetadata.InjectedElement createAutowiredFieldElement(Field field, boolean required) {
	return new AutowiredFieldElement(field, required);
}
 
private Map<String, Map<String, Object>> buildReferencesMetadata(
        Map<InjectionMetadata.InjectedElement, ReferenceBean<?>> injectedElementReferenceBeanMap) {
    Map<String, Map<String, Object>> referencesMetadata = new LinkedHashMap<>();

    for (Map.Entry<InjectionMetadata.InjectedElement, ReferenceBean<?>> entry :
            injectedElementReferenceBeanMap.entrySet()) {

        InjectionMetadata.InjectedElement injectedElement = entry.getKey();

        ReferenceBean<?> referenceBean = entry.getValue();

        Map<String, Object> beanMetadata = resolveBeanMetadata(referenceBean);
        beanMetadata.put("invoker", resolveBeanMetadata(referenceBean.get()));

        referencesMetadata.put(String.valueOf(injectedElement.getMember()), beanMetadata);

    }

    return referencesMetadata;
}
 
/**
 * Get {@link Map} in injected field.
 *
 * @return non-null ready-only {@link Map}
 */
protected Map<InjectionMetadata.InjectedElement, Object> getInjectedFieldObjectsMap() {

    Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
            new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();

    for (AbstractAnnotationBeanPostProcessor.AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {

        Collection<AbstractAnnotationBeanPostProcessor.AnnotatedFieldElement> fieldElements = metadata.getFieldElements();

        for (AbstractAnnotationBeanPostProcessor.AnnotatedFieldElement fieldElement : fieldElements) {

            injectedElementBeanMap.put(fieldElement, fieldElement.bean);

        }

    }

    return Collections.unmodifiableMap(injectedElementBeanMap);

}
 
private List<InjectionMetadata.InjectedElement> findMethodReferenceMetadata(final Class<?> beanClass) {

        final List<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();

        ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
            @Override
            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {

                Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);

                if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
                    return;
                }
                
            	Inject inject = findReferenceAnnotation(bridgedMethod);
                if (inject == null) {
                	return;
                }
                if(!method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))){
                	return;
                }
                if (Modifier.isStatic(method.getModifiers())) {
                    logger.warn("@Reference 静态方法不支持注释: {}" , method);
                    return;
                }
                if (method.getParameterTypes().length == 0) {
                	logger.warn("@Reference  注释应该只使用有参数的方法: {}" , method);
                	return;
                }
                if(method.getParameterTypes().length>1){
                	logger.warn("@Reference  注释应该只使用有一个参数的方法: {}" , method);
                	throw new IllegalArgumentException("@Reference  注释应该只使用有一个参数的方法");
                }
            	Class<?> requiredType = method.getParameterTypes()[0];
            	Object bean= getBean(inject, requiredType);
            	PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
                if(bean!=null){
                	elements.add(injectBeanPostProcessor.createAutowiredMethodElement(bridgedMethod, true, pd));
                	return;
                }
                elements.add(new ReferenceMethodElement(method, pd, inject.value()));
            }
        });

        return elements;

    }
 
/**
 * Get {@link Map} in injected field.
 *
 * @return non-null ready-only {@link Map}
 */
protected Map<InjectionMetadata.InjectedElement, Object> getInjectedFieldObjectsMap() {

    Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
            new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();

    for (AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {

        Collection<AnnotatedFieldElement> fieldElements = metadata.getFieldElements();

        for (AnnotatedFieldElement fieldElement : fieldElements) {

            injectedElementBeanMap.put(fieldElement, fieldElement.bean);

        }

    }

    return Collections.unmodifiableMap(injectedElementBeanMap);

}
 
/**
 * Get {@link Map} in injected method.
 *
 * @return non-null {@link Map}
 */
protected Map<InjectionMetadata.InjectedElement, Object> getInjectedMethodObjectsMap() {

    Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
            new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();

    for (AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {

        Collection<AnnotatedMethodElement> methodElements = metadata.getMethodElements();

        for (AnnotatedMethodElement methodElement : methodElements) {

            injectedElementBeanMap.put(methodElement, methodElement.object);

        }

    }

    return Collections.unmodifiableMap(injectedElementBeanMap);

}
 
@Test
public void testGetInjectedFieldReferenceBeanMap() {

    ReferenceAnnotationBeanPostProcessor beanPostProcessor = context.getBean(BEAN_NAME,
            ReferenceAnnotationBeanPostProcessor.class);


    Map<InjectionMetadata.InjectedElement, ReferenceBean<?>> referenceBeanMap =
            beanPostProcessor.getInjectedFieldReferenceBeanMap();

    Assert.assertEquals(1, referenceBeanMap.size());

    for (Map.Entry<InjectionMetadata.InjectedElement, ReferenceBean<?>> entry : referenceBeanMap.entrySet()) {

        InjectionMetadata.InjectedElement injectedElement = entry.getKey();

        Assert.assertEquals("com.alibaba.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor$AnnotatedFieldElement",
                injectedElement.getClass().getName());

        ReferenceBean<?> referenceBean = entry.getValue();

        Assert.assertEquals("2.5.7", referenceBean.getVersion());
        Assert.assertEquals("dubbo://127.0.0.1:12345", referenceBean.getUrl());

    }

}
 
private InjectionMetadata buildReferenceMetadata(final Class<?> beanClass) {

        final List<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();

        elements.addAll(findFieldReferenceMetadata(beanClass));

        elements.addAll(findMethodReferenceMetadata(beanClass));

        return new InjectionMetadata(beanClass, elements);

    }
 
/**
 * Subclass must implement this method to get injected-object. The context objects could help this method if
 * necessary :
 * <ul>
 * <li>{@link #getBeanFactory() BeanFactory}</li>
 * <li>{@link #getClassLoader() ClassLoader}</li>
 * <li>{@link #getEnvironment() Environment}</li>
 * </ul>
 *
 * @param annotation      {@link A annotation}
 * @param bean            Current bean that will be injected
 * @param beanName        Current bean name that will be injected
 * @param injectedType    the type of injected-object
 * @param injectedElement {@link InjectionMetadata.InjectedElement}
 * @return The injected object
 * @throws Exception If resolving an injected object is failed.
 */
protected abstract Object doGetInjectedBean(A annotation, Object bean, String beanName, Class<?> injectedType,
                                            InjectionMetadata.InjectedElement injectedElement) throws Exception;
 
/**
 * Build a cache key for injected-object. The context objects could help this method if
 * necessary :
 * <ul>
 * <li>{@link #getBeanFactory() BeanFactory}</li>
 * <li>{@link #getClassLoader() ClassLoader}</li>
 * <li>{@link #getEnvironment() Environment}</li>
 * </ul>
 *
 * @param annotation      {@link A annotation}
 * @param bean            Current bean that will be injected
 * @param beanName        Current bean name that will be injected
 * @param injectedType    the type of injected-object
 * @param injectedElement {@link InjectionMetadata.InjectedElement}
 * @return Bean cache key
 */
protected abstract String buildInjectedObjectCacheKey(A annotation, Object bean, String beanName,
                                                      Class<?> injectedType,
                                                      InjectionMetadata.InjectedElement injectedElement);