您的位置:首页 > 编程语言 > Java开发

spring ListableBeanFactory接口中getBeansOfType和BeanFactory接口的isTypeMatch方法实现分析

2017-09-28 10:58 836 查看
public interface ListableBeanFactory extends BeanFactory {

........

<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException;

........

}

public interface ListableBeanFactory extends BeanFactory {

........

boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;

........

}

ListableBeanFactory接口,继承自BeanFactory接口。DefaultListableBeanFactory类可以认为是ListableBeanFactory接口的一个常用实现。



根据类型获取bean,即getBeansOfType方法,依赖于isTypeMatch。

以DefaultListableBeanFactory为例,getBeansOfType方法内部的核心实现是调用doGetBeanNamesForType方法,private String[] doGetBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) 。在spring中,真正干事的都是do×××方法。

doGetBeanNamesForType方法内,会先获取目前已有的所有的bean名字String[] beanDefinitionNames = getBeanDefinitionNames();,然后循环比较每个bean是否符合类型要求,如果符合,添加到结果集合内,List<String> result = new ArrayList<String>();,最后将result结合返回。

判断bean是否符合类型要求时,需要用到isTypeMatch接口实现,在AbstractBeanFactory类内。AbstractBeanFactory.isTypeMatch方法内,会根据beanName获取对应的RootBeanDefinition对象属性RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);,然后通过调用AbstractAutowireCapableBeanFactory.predictBeanType方法找到beanName对应的class类,Class<?>
beanType = predictBeanType(beanName, mbd, typesToMatch);。predictBeanType方法内,会根据beanName找到对应的class值,一般是从RootBeanDefinition属性中getBeanClass方法获取mbd.getBeanClass();,如果有hasInstantiationAwareBeanPostProcessors的情况,会稍微复杂一点,这里不做说明。总之,predictBeanType方法会返回beanName对应的class类。isTypeMatch方法内,最终是用这个返回类和参数中的class类进行对应的。

对比两个类型是否相等的代码只有一句,typeToMatch.isAssignableFrom(beanType);,这是个本地方法,无法追查代码。typeToMatch是isTypeMatch(String name, Class<?>targetType)中targetType的简单处理后的值,Class<?>
typeToMatch = (targetType != null ? targetType : Object.class);,beanType是predictBeanType方法中根据beanName获取的对应的class类,Class<?> beanType = predictBeanType(beanName, mbd, typesToMatch);
Class类isAssignableFrom方法说明

public final class Class<T> implements java.io.Serializable,

                              GenericDeclaration,

                              Type,

                              AnnotatedElement {

...........

public native boolean isAssignableFrom(Class<?> cls);

...........

}

instanceof 针对实例 

isAssignableFrom针对class对象

 

isAssignableFrom   是用来判断一个类Class1和另一个类Class2是否相同或是另一个类的超类或接口。   

通常调用格式是  

Java代码  


Class1.isAssignableFrom(Class2)     

 

调用者和参数都是   java.lang.Class   类型。   

public class Test {  

    public static void main(String[] args) {  

        List<String> list = new ArrayList<String>();  

        System.out.println(list instanceof List);  

        System.out.println(list instanceof ArrayList);  

          

        System.out.println(list.getClass().isAssignableFrom(List.class));  

        System.out.println(List.class.isAssignableFrom(list.getClass()));  

    }  

}  

结果:

true

true

false

true

其中instanceof是子-->父 

isAssignableFrom是父-->子

list.getClass() = class java.util.ArrayList
List.class
= interface java.util.List

List ×× = ArrayList
可以

ArrayList ×× = List 报错

boolean java.lang.Class.isAssignableFrom(Class<?>
cls)

Determines if the class or interface represented by this
Class
object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified
Class
parameter. It returns
true

if so; otherwise it returns
false
. If this
Class
object represents a primitive type, this method returns
true
if the specified
Class
parameter is exactly this
Class
object; otherwise it returns
false
.

Specifically, this method tests whether the type represented by the specified
Class
parameter can be converted to the type represented by this
Class
object via an identity conversion or via a widening reference conversion. SeeThe Java Language Specification, sections 5.1.1 and 5.1.4 , for details.

Parameters:cls the
Class
object to be checkedReturns:the
boolean
value indicating whether objects of the type
cls
can be assigned to objects of this classThrows:NullPointerException - if the specified Class parameter is null.Since:JDK1.1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐