下面列出了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);