zoukankan      html  css  js  c++  java
  • BeanDefinition及其实现类

     

    目录(?)[+]

     

    一、 BeanDefinition及其实现类

    BeanDefinition接口

    这个接口描述bean的结构,对应XML中的< bean >或者配置类中的@Bean 
    它集成了BeanMetadataElement和AttributeAccessor,如下图 
    这里写图片描述 
    【AttributeAccessor接口】 
    类似于map,具有保存和访问name/value属性的能力

    public interface AttributeAccessor { 
        void setAttribute(String name, Object value); 
        Object getAttribute(String name); 
        Object removeAttribute(String name); 
        boolean hasAttribute(String name); 
        String[] attributeNames(); 
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    【BeanMetadataElement接口】 
    实现此接口的类,访问source(配置源)的能力

    public interface BeanMetadataElement { 
        Object getSource(); 
    }
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    【BeanDefinition接口】 
    定义了设置、获取一个BeanDefinition属性方便方法(比如获取scope属性直接使用getScope())

    public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    
        //单例或原型
        String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON; 
        String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
    
         //Bean角色
        int ROLE_APPLICATION = 0; 
        int ROLE_SUPPORT = 1; 
        int ROLE_INFRASTRUCTURE = 2;
    
        // 返回/设置父BeanDefinition 
        String getParentName(); 
        void setParentName(String parentName);
    
        //返回/设置 当前的BeanClassName(不等于最终Bean的名称)
        String getBeanClassName(); 
        void setBeanClassName(String beanClassName);
    
        //返回设置 factory bean name  
        String getFactoryBeanName(); 
        void setFactoryBeanName(String factoryBeanName);
    
        String getFactoryMethodName(); 
        void setFactoryMethodName(String factoryMethodName);
    
        String getScope(); 
        void setScope(String scope);
    
        boolean isLazyInit(); 
        void setLazyInit(boolean lazyInit);
    
        String[] getDependsOn(); 
        void setDependsOn(String... dependsOn);
    
        boolean isAutowireCandidate(); 
        void setAutowireCandidate(boolean autowireCandidate);
    
        boolean isPrimary(); 
        void setPrimary(boolean primary);
    
        ConstructorArgumentValues getConstructorArgumentValues();
    
        MutablePropertyValues getPropertyValues(); 
        boolean isSingleton(); 
        boolean isPrototype(); 
        boolean isAbstract(); 
        int getRole(); 
        String getDescription(); 
        String getResourceDescription(); 
        BeanDefinition getOriginatingBeanDefinition();
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    BeanDefinition的子接口和实现类

    这里写图片描述

    【AnnotatedBeanDefinition 接口】

    这个接口可以获取BeanDefinition注解相关数据

    public interface AnnotatedBeanDefinition extends BeanDefinition { 
        AnnotationMetadata getMetadata(); 
        MethodMetadata getFactoryMethodMetadata(); 
    }
    • 1
    • 2
    • 3
    • 4
    • 1
    • 2
    • 3
    • 4

    【AbstractBeanDefinition】

    这个抽象类的构造方法设置了BeanDefinition的默认属性,重写了equals,hashCode,toString方法。

    【ChildBeanDefinition】

    可以从父BeanDefinition中集成构造方法,属性等

    【RootBeanDefinition】

    代表一个从配置源(XML,Java Config等)中生成的BeanDefinition

    GenericBeanDefinition

    GenericBeanDefinition是自2.5以后新加入的bean文件配置属性定义类,是ChildBeanDefinition和RootBeanDefinition更好的替代者

    【AnnotatedGenericBeanDefinition】

    对应注解@Bean

    @Component("t")
    public class Tester {
        public static void main(String[] args) throws Exception {
            AnnotatedGenericBeanDefinition beanDefinition=new AnnotatedGenericBeanDefinition(Tester.class);
            System.out.println(beanDefinition.getMetadata().getAnnotationTypes());
            System.out.println(beanDefinition.isSingleton());
            System.out.println(beanDefinition.getBeanClassName()); 
        }
    }
    
    ==========输出==============
    [org.springframework.stereotype.Component]
    true
    Tester
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    二 、BeanDefinitionHolder

    BeanDefinitionHolder

    持有一个BeanDefinition,名称,和别名数组。在spring内部,它用来临时保存BeanDefinition来传递BeanDefinition。 
    它的部分方法如下:

    public class BeanDefinitionHolder implements BeanMetadataElement {
    
        private final BeanDefinition beanDefinition;
        private final String beanName;
        private final String[] aliases; 
    
        public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName, String[] aliases) {
            Assert.notNull(beanDefinition, "BeanDefinition must not be null");
            Assert.notNull(beanName, "Bean name must not be null");
            this.beanDefinition = beanDefinition;
            this.beanName = beanName;
            this.aliases = aliases;
        }  
        public BeanDefinition getBeanDefinition() {
            return this.beanDefinition;
        } 
        public String getBeanName() {
            return this.beanName;
        } 
        public String[] getAliases() {
            return this.aliases;
        }
        //其他方法...省略
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    三、BeanDefinitionRegistry接口

    这个接口定义了‘注册/获取BeanDefinition’的方法 。 
    接口定义:

    public interface BeanDefinitionRegistry extends AliasRegistry {
        //注册一个BeanDefinition  
        void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
                throws BeanDefinitionStoreException; 
        //根据name,从自己持有的多个BeanDefinition 中 移除一个 
        void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
        // 获取某个BeanDefinition
        BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; 
        boolean containsBeanDefinition(String beanName);//是否包含 
        String[] getBeanDefinitionNames();//获取所有名称 
        int getBeanDefinitionCount();//获取持有的BeanDefinition数量 
        boolean isBeanNameInUse(String beanName); //判断某个BeanDefinition是否在使用
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    实现类一般使用Map保存多个BeanDefinition,如下:

    Map<String, BeanDefinition> beanDefinitionMap = new HashMap<String, BeanDefinition>();
    • 1
    • 1

    实现类有SimpleBeanDefinitionRegistry,DefaultListableBeanFactoryGenericApplicationContext等。

    SimpleBeanDefinitionRegistry

    SimpleBeanDefinitionRegistry是最基本的实现类。 
    使用:

    public static void main(String[] args) throws Exception {
    
        //实例化SimpleBeanDefinitionRegistry
        SimpleBeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
    
        //注册两个BeanDefinition
        BeanDefinition definition_1 = new GenericBeanDefinition();
        registry.registerBeanDefinition("d1", definition_1);
    
        BeanDefinition definition_2 = new RootBeanDefinition();
        registry.registerBeanDefinition("d2", definition_2);
    
        //方法测试
        System.out.println(registry.containsBeanDefinition("d1"));//true
        System.out.println(registry.getBeanDefinitionCount());//2
        System.out.println(Arrays.toString(registry.getBeanDefinitionNames()));//[d1, d2] 
    }
    
    ================结果==================
    true
    2
    [d1, d2]
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    四、BeanDefinitionReader接口

    BeanDefinitionRegistry接口一次只能注册一个BeanDefinition,而且只能自己构造BeanDefinition类来注册。BeanDefinitionReader解决了这些问题,它一般可以使用一个BeanDefinitionRegistry构造,然后通过#loadBeanDefinitions(..)等方法,把“配置源”转化为多个BeanDefinition并注册到BeanDefinitionRegistry中 。 
    可以说BeanDefinitionReader帮助BeanDefinitionRegistry实现了高效、方便的注册BeanDefinition。

    BeanDefinitionReader接口定义如下:

    public interface BeanDefinitionReader {
        //获取BeanDefinitionRegistry 
        BeanDefinitionRegistry getRegistry();
    
        ResourceLoader getResourceLoader();
    
        ClassLoader getBeanClassLoader(); 
    
        //获取Bean的名称生成器
        BeanNameGenerator getBeanNameGenerator();
    
        //载入BeanDefinition
        int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException;
    
         //载入BeanDefinition
        int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException;
    
         //载入BeanDefinition
        int loadBeanDefinitions(String location) throws BeanDefinitionStoreException;
    
         //载入BeanDefinition
        int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException;
    
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    类的体系结构

    这里写图片描述

    AbstractBeanDefinitionReader:实现了EnvironmentCapable,提供了获取/设置环境的方法。定义了一些通用方法,使用策略模式,将一些具体方法放到子类实现。 
    XmlBeanDefinitionReader:读取XML文件定义的BeanDefinition 
    PropertiesBeanDefinitionReader:可以从属性文件,Resource,Property对象等读取BeanDefinition 
    GroovyBeanDefinitionReader:可以读取Groovy语言定义的Bean

    实现类:XmlBeanDefinitionReader

    把xml配置文件转化成beanDefinition

    这个类就不做演示了
    • 1
    • 1

    实现类: PropertiesBeanDefinitionReader

    可以从Properties文件读取BeanDefinition,文件可以是如下结构:

    #bean名称.(属性)=值
    ==========================
    mybean.(class)=PropertyReaderTest
    mybean.(abstract)=true 
    mybean.(lazy-init)=true
    mybean.(scope)=prototype    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    程序实例:

    public class PropertyReaderTest {
        public static void main(String[] args) {
            //定义BeanDefinitionRegistry 
            BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry(); 
            //使用BeanDefinitionRegistry实例 构造BeanDefinitionReader
            PropertiesBeanDefinitionReader reader = new PropertiesBeanDefinitionReader(registry);
            //载入文件
            reader.loadBeanDefinitions("config.properties");
    
            System.out.println(registry.getBeanDefinition("mybean"));
        }
    } 
    
    ================输出=================
    .......//日志信息 略
    Generic bean: class [PropertyReaderTest]; scope=prototype; abstract=true; lazyInit=true; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    五、读取注解定义的BeanDefinition

    注解相关的BeanDefinitionReader并没有实现BeanDefinitionReader接口,有如下类:

    AnnotatedBeanDefinitionReader类

    使用如下:

    SimpleBeanDefinitionRegistry registry= new SimpleBeanDefinitionRegistry();
    AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(registry);
    reader.register(Tester.class);
    System.out.println( registry.getBeanDefinitionCount());
    
    =========================
    7 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    我们只注册了一个Bean,为什么出现7个呢?原来是AnnotatedBeanDefinitionReader 向BeanDefinitionRegistry自动注册了6个BeanDefinition。这个在以后章节中详解。

    ClassPathBeanDefinitionScanner

    ClassPathBeanDefinitionScanner 继承自ClassPathScanningCandidateComponentProvider 
    类结构如下: 
    这里写图片描述

    【ClassPathScanningCandidateComponentProvider】 
    这个类的findCandidateComponents可以扫描到@Component @Repository @Service @Controller 的BeanDefinition,并加入Set 集合中

    ClassPathScanningCandidateComponentProvider provider=new ClassPathScanningCandidateComponentProvider(true); 
    Set<BeanDefinition> definitionSet= provider.findCandidateComponents("com.jazz.web");
    System.out.println(definitionSet.size());
    • 1
    • 2
    • 3
    • 1
    • 2
    • 3

    【ClassPathBeanDefinitionScanner】

    这里写代码片
  • 相关阅读:
    Android 程序架构: MVC、MVP、MVVM、Unidirectional、Clean...
    asp.net发布到IIS中出现错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”
    反射中使用 BindingFlags.IgnoreCase
    JQuery判断数组中是否包含某个元素$.inArray("js", arr);
    Sql日期时间格式转换
    c#组元(Tuple)的使用
    逆向最大匹配分词算法C#
    [WEB API] CLIENT 指定请求及回应格式(XML/JSON)
    Jquery 将表单序列化为Json对象
    JS调试加断点
  • 原文地址:https://www.cnblogs.com/lupeng2010/p/7028742.html
Copyright © 2011-2022 走看看