Spring进阶-Spring Bean

什么是Spring Bean

什么是Spring Bean呢?官方文档中是这么介绍的:

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.

翻译成中文的意思是:「在Spring中,构成应用程序主干并有Spring IOC容器管理的对象称为Bean。Bean是由Spring IOC容器实例化、组装和管理的对象,否则Bean只是程序许多对象中的一个。Bean以及它们之间的依赖关系反映在容器使用的配置元数据中。」
这段话总结下来就是这么几个意思:

  • Spring Bean就是一个个组件,它们共同组成了应用程序。
  • Spring Bean是由IOC容器来管理的。
  • Spring Bean之间的依赖关系配置在IOC容器中。
    对于什么是IOC容器可以参考我之前写的《Spring进阶-BeanFactory》一文中,其中有对IOC的解释。

BeanDefinition与Bean之间的关系

关于什么是BeanDefinition,在之前的写的《Spring进阶-BeanDefinition》一文中有介绍,简单的说就是我们在IOC容器中配置的Bean信息,不管是XML形式、JavaConfig形式、还是其他形式定义的,这些信息统统都会被解析出来后使用BeanDefinition封装起来。对于Bean和BeanDefinition之间的关系你可以类比成「类实例」「类」之间的关系。

如何实例化一个Bean

从上面我们知道了什么是Spring Bean,现在的问题是如何实例化一个Spring Bean呢?从官方文档上来说,通常有这么几种方式:通过构造函数、通过静态工厂方法、通过实例化工厂方法。

构造函数

在使用构造函数实例化Bean时,我们即可以通过无参构造函数实例化Bean,同时也可以使用有参构造函数示例化Bean,只需要我们有对应的构造函数即可。

  • spring-bean-1.xml配置文件
    <!--    无参构造函数-->
    <bean id="benchi" class="com.buydeem.share.bean.Car">
        <property name="name" value="奔驰"/>
        <property name="color" value="灰色"/>
    </bean>

    <!--    有参构造函数-->
    <bean id="bmw" class="com.buydeem.share.bean.Car">
        <constructor-arg name="name" value="宝马"/>
        <constructor-arg name="color" value="黑色"/>
    </bean>
  • 示例代码
public class BeanDemo1 {
    public static void main(String[] args) {
        //创建IOC容器
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        //加载BeanDefinition配置文件
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions("spring-bean-1.xml");

        //遍历Bean
        String[] beanDefinitionNames = factory.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Car car = factory.getBean(beanDefinitionName, Car.class);
            System.out.println(car);
        }
    }
}

@Data
class Car{
    private String name;
    private String color;

    public Car(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public Car() {
    }
}

运行结果如下:

Car(name=奔驰, color=灰色)
Car(name=宝马, color=黑色)

从打印结果可以看出,我们的确是通过构造函数创建了Bean。在通过构造函数创建Bean时,BeanDefinition中的class指的就是要创建的类的全名称。

静态工厂方法

除了使用构造函数来实例化Bean之外,我们还可以使用静态工厂的方式来创建Bean。使用静态工厂这种方式,我们的class指定的不再是实例的类名称,而是静态工厂类的全名称。同时我们还需要指定静态工厂方法,也就是XML中的「factory-method」方法名称。

  • spring-bean-2.xml配置文件
    <!--    无参静态方法-->
    <bean id="jieda" class="com.buydeem.share.bean.CarStaticFactory" factory-method="getInstance"/>

    <!--    有参静态方法-->
    <bean id="bmw" class="com.buydeem.share.bean.CarStaticFactory" factory-method="getInstance">
        <constructor-arg name="name" value="宝马"/>
        <constructor-arg name="color" value="黑色"/>
    </bean>
  • Java代码
public class BeanDemo2 {
    public static void main(String[] args) {
        //创建IOC容器
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        //加载BeanDefinition配置文件
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions("spring-bean-2.xml");

        //遍历Bean
        String[] beanDefinitionNames = factory.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Car car = factory.getBean(beanDefinitionName, Car.class);
            System.out.println(car);
        }
    }
}

class CarStaticFactory{
    private static Car car = new Car("捷达","银色");

    private CarStaticFactory(){}

    public static Car getInstance(){
        return car;
    }

    public static Car getInstance(String name,String color){
        return new Car(name,color);
    }
}
  • 打印结果
Car(name=捷达, color=银色)
Car(name=宝马, color=黑色)

从打印结果可以看出,通过静态工厂方法可以实例化Bean,同样我们可以在静态方法中指定方法参数。在使用该方式时,我们需要注意的是「class」「factory-method」设置即可。

实例化工厂

该方式与静态工厂方式类似,不同的点在于我们需要先定义实例工厂,在定义实例Bean时指定的「factory-bean」「factory-method」,而「class」设置为空即可。

  • spring-bean-3.xml配置
<!--    实例工厂-->
    <bean id="carFactory" class="com.buydeem.share.bean.CarFactory"/>
    <!--    无参实例工厂方法-->
    <bean id="jieda" factory-bean="carFactory" factory-method="createCar"/>
    <!--    有参实例工厂方法-->
    <bean id="bmw" factory-bean="carFactory" factory-method="createCar">
        <constructor-arg name="name" value="宝马"/>
        <constructor-arg name="color" value="黑色"/>
    </bean>
  • Java代码
public class BeanDemo3 {
    public static void main(String[] args) {
        //创建IOC容器
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        //加载BeanDefinition配置文件
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions("spring-bean-3.xml");

        //遍历Bean
        String[] beanDefinitionNames = factory.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            Object bean = factory.getBean(beanDefinitionName);
            System.out.println(bean);
        }
    }
}

class CarFactory{

    public CarFactory() {
    }

    public Car createCar(){
        return new Car("捷达","黑色");
    }

    public Car createCar(String name,String color){
        return new Car(name,color);
    }
}
  • 打印结果
com.buydeem.share.bean.CarFactory@5d740a0f
Car(name=捷达, color=黑色)
Car(name=宝马, color=黑色)

小结

通过上面的阅读,我们主要了解什么是Spring Bean以及如何实例化Spring Bean。当然与Spring相关的东西还有很多没有讲到,后续我还会继续更新《Spring进阶》相关知识,在后面的文章中我会一点点仔细把他们讲清楚。


原文始发于微信公众号(一只菜鸟程序员):Spring进阶-Spring Bean

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/73005.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之家——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!