zoukankan      html  css  js  c++  java
  • spring-bean总览和实例化

    一 说明

    现在开发比较流行springboot,但很多开发人员都忽略l了springboot是基于spring而衍生的子项目,不懂spring如何玩转springboot?难道就靠几天的培训跟文章就能玩转springboot了么?答案肯定是不行的,要深入了解springboot必须要会spring,基础很重要,重要的话再怎么说都不为过;作者写spring的基础文章和概念性的理解还有一个很重要的目的,那就是为后面的分析源码做准备,如果一下子就上源码,我相信很多人都会被绕进去,都不知道回事,所以老老实实的学习才是技术提升的必经之路。有兴趣的开发人员或者学生可以关注我的sping专栏。

    二 bean 简介

    由于之前的文章已经讲过beans包和核心概念就不赘述。spring IOC container 可以容纳一个或者多个beans,beans的是随着 configuration metadata 的提供而创建的,configuration metadata 之前文章也提过,其最原始的配置方式就xml.

    这些bean的定义其实就是对应BeanDefinition Object。下面源码一句话;BeanDefinition(接口) 就是 bean的一个实例,其有属性值,构造参数值和更深层次的信息,这些由其具体的实现者提供。

    A BeanDefinition describes a bean instance, which has property values,constructor argument values,
    and further information supplied by
    concrete implementations.

    BeanDefinition 的 元数据举例:

    1. bean的声明周期和作用域(scop,lifecycle callbacks)
    2. 包限定的类名:通常就是真实类的全类名
    3. 在container直接的相互协作依赖。
    4. 在创建对象的时候配置其他信息,比如使用bean管理连接池,限值连接池的大小等。

    通常元数据就是转为属性

    1. class (bean全类名)
    2. name (bean的名称)
    3. scope (作用域)
    4. constructor arguments (构造器参数)
    5. properties (属性)
    6. autowiring mode (自动配置模式)
    7. lazy-initialization mode (懒初始化模式)
    8. initialization method (bean初始化方法)
    9. destruction method (bean摧毁方法)

    此外还可以通过 ApplicationContext 的实现者(比如使用getBeanFactory()获得DefaultListableBeanFactory)通过registerSingleton方法和registerBeanDefinition方法去配置元数据,但这种方式不常见,通常都是使用xml

    三 bean的命名

    每一个bean通常都是有一个或者多个身份,使用bean的别名等,但是container在管理bean时其必须要有唯一标识。通常基于xml配置元数据,<bean> 元素的 id , name 属性通常就代表了一个bean的唯一标识。命名的规则是第一个字母小写后面的字母或者数字使用驼峰比如 userDao , userService 。通常 不指定 bean的名称也是可以,spring container 会自动给bean生成一个唯一标识,但是,如果要按名称引用该bean,则必须通过使用ref元素或 Service Locator 样式查找提供名称。

    四 别名

    通常在大型的项目中会使用到别名,比如主系统和子系统集成的时候 一个bean在相同的container中称为fromName,使用别名后就会指向toName,示例如下:

    <alias name="fromName" alias="toName"/>
    

    五 bean的实例化

    bean的实例化方式其实可以分为三种,第一种就是直接使用bean元素,container初始化后,直接拿到bean的实例,这跟平时new 对象没啥区别,但是默认情况下由container的bean实例化后拿到的实例都是单例。第二种就是使用static factory-method,(静态工厂模式)。第三种就是 factory-method (实例工厂模式)。第二种和第三种这两种方式不是很常见,container在初始化的时候会调用fatory-method实例化bean,fatory-method会去工厂中调用创建实例的方法(createInstance)。

    区别是否是内部类通常使用$区分,比如 com.youku1327. Animal$$dog

    5.1 使用构造器的方式实例化bean

    示例如下,有使用spring框架开发的人员肯定很熟悉,我们经常使用这种方式实例化bean

    	<bean id="iocService" class="com.youku1327.ioc.service.IocService">
            <!-- additional collaborators and configuration for this bean go here -->
        </bean>
    

    5.2 使用 static factory method 实例化bean

    静态工厂 如下,本示例的fatory-method的静态工厂就是其本身(你也可以 new 其他的实例放进静态工厂里面),但是 其声明方法类型必须是static。

    /**
     * @Author lsc
     * @Description <p> </p>
     * @Date 2019/10/31 13:55
     */
    public class StaticBeanService {
    
        private static StaticBeanService staticBeanService = new StaticBeanService();
    
        // other properties
    
        private StaticBeanService() {}
    
        public static StaticBeanService createInstance() {
            // add your properties
            return staticBeanService;
        }
    
    }
    

    配置如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!-- static factory method services -->
    
        <bean id="staticBeanService" class="com.youku1327.bean.entity.StaticBeanService" factory-method="createInstance">
    
        </bean>
        
    </beans>
    

    5.3 使用 instance factory method 实例化bean

    实例化工厂模式和静态工厂模式很相似,区别在于创建实例的方法有没有使用static关键字而已。本实例的Car其实应该是接口,然后通过具体的实现类(比如兰博基尼Car,宝马car等)实现接口,然后在Carfactory中使用相应的createCarInstance方法,在xml中配置对应的bean即可。简单的实现示例如下:

    实体如下:

    /**
     * @Author lsc
     * @Description <p> </p>
     * @Date 2019/10/31 14:58
     */
    public class Car {
    
        private String carName;
        private String color;
    
        public String getCarName() {
            return carName;
        }
    
        public void setCarName(String carName) {
            this.carName = carName;
        }
    
        public String getColor() {
            return color;
        }
    
        public void setColor(String color) {
            this.color = color;
        }
    }
    

    实例化工厂如下:

    /**
     * @Author lsc
     * @Description <p> </p>
     * @Date 2019/10/31 15:00
     */
    public class CarFactory {
    
        private static Car car = new Car();
    
        private CarFactory(){
    
        }
    
        public Car createCarInstance(){
            return car;
        }
    }
    

    配置如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!-- the factory bean, which contains a method called createInstance() -->
        <bean id="carFactory" class="com.youku1327.bean.factory.CarFactory">
            <!-- inject any dependencies required by this locator bean -->
        </bean>
    
        <!-- the bean to be created via the factory bean -->
        <bean id="car" factory-bean="carFactory" factory-method="createCarInstance"/>
    
    
    </beans>
    

    六 参考文档

    IOC Container

    【本文github源码在公众号文章末尾链接】。

  • 相关阅读:
    网络编程基础【day10】:多线程效果演示(二)
    网络编程基础【day10】:进程与线程介绍(一 )
    第四模块:网络编程基础
    第三模块:面向对象(目录)
    网络编程基础【day09】:堡垒机前戏(十一)
    网络编程基础【day09】:socketserver进阶(十)
    网络编程基础【day09】:socketserver使用(九)
    网络编程基础【day09】:socket解决粘包问题之MD5(八)
    网络编程基础【day09】:socket接收大数据(五)
    网络编程基础【day09】:socket实现文件发送(六)
  • 原文地址:https://www.cnblogs.com/zszxz/p/12696944.html
Copyright © 2011-2022 走看看