Spring源码(二-3)-XML文件的读取-factory-method的使用

简介: Spring 可以通过 factory-method 实例化对象。factory-method方式是 Spirng 实例对象的方式之一。
日积月累,水滴石穿 😄

Spring可以通过factory-method实例化对象。factory-method方式是 Spirng 实例对象的方式之一。

创建对象的方式有两种方式:

  • 一种是静态工厂注入(其中的方法必须是静态的)。
  • 另一种是实例工厂注入。

下面一起来看看两种方式的使用方式

静态工厂注入

创建 A 对象,提供基本的属性和 get、set方法、构造函数、toString 方法。

public class A {

    private String name;

    private String email;

    public A() {
    }

    public A(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "A{" +
                "name='" + name + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

静态工厂类

public class AFactory {

    private static A a;

    //静态方法 创建 A 对象
    public static A getInstance(String name){
        return  new A(name);
    }
}

添加配置

<!--静态获取Bean对象-->
<bean id="aFactory" class="com.gongj.factoryMethod.AFactory"
      factory-method="getInstance">
    <!--getInstance方法的参数-->
    <constructor-arg index="0" value="GONGJ"></constructor-arg>
</bean>

class 属性指定工厂类的路径;factory-method 属性指定工厂类中静态方法constrctor-arg 属性用于给静态方法传递参数。

测试

public static void main(String[] args) {
    ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext("factoryMethod.xml");
    Object aFactory = cxt.getBean("aFactory");
    System.out.println("结果:" +aFactory);
}
结果:A{name='GONGJ', email='null'}

当然也可以指定参数获得对象:

Object aFactory = cxt.getBean("aFactory","哈哈哈哈");
System.out.println("结果:" +aFactory);

结果:A{name='哈哈哈哈', email='null'}

指定参数这种方式需要将 aFactory 的作用域改为 prototype。这里使用的 ClassPathXmlApplicationContext 容器,容器启动的时候就将 aFactory 创建了(懒加载单例bean),并使用 xml 指定的构造函数创建A

实例工厂注入

实例工厂方式需要先实例化工厂类,然后再通过已经实例化的工厂对象中一个方法来创建bean,并注入到容器中。

还是使用上面使用的 AFactory 类,在其中增加方法 getInstanceMethod,与上述 getInstance 方法就少了一个 static 关键字。

public A getInstanceMethod(String name){
   
       return new A(name);
    
}

修改配置

<!--实例化工厂类-->
<bean class="com.gongj.factoryMethod.AFactory" id="aFactory"></bean>
<!--实例化A对象 factory-bean配置实例化工厂类的名称  factory-method配置工厂类里的实例方法-->
<bean class="com.gongj.factoryMethod.A" id="a"
      factory-bean="aFactory" factory-method="getInstanceMethod">
    <constructor-arg index="0" value="yuanj"></constructor-arg>
</bean>

测试

public static void main(String[] args) {
        ClassPathXmlApplicationContext cxt = new ClassPathXmlApplicationContext("factoryMethod.xml");
        Object a = cxt.getBean("a");
        System.out.println("结果:" +a);
}
结果:A{name='yuanj', email='null'}

也是可以指定参数获得对象:

Object a= cxt.getBean("a","哈哈哈哈");
System.out.println("结果:" +a);

结果:A{name='哈哈哈哈', email='null'}

这种方式需要将 a 的作用域改为 prototype

各位也会发现,两种方式获得对象的方式不一样。静态工厂创建对象时获取的对象是 cxt.getBean("aFactory");,而实例工厂创建对象时获取的对象是cxt.getBean("a");,当然两种方式返回的对象都是 A

学会了使用,我们看看源码是如何被解析的:直接进入 BeanDefinitionParserDelegate 类的 parseBeanDefinitionAttributes 方法,其中有这一段代码:

//解析 factory-method 属性
if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
    bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
}
//解析 factory-bean 属性
if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
    bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
}

很简单,获取 bean 标签里的 factory-method 属性的值,并赋值给 AbstractBeanDefinitionfactoryMethodName属性,获取 bean 标签里的 factory-bean 属性的值,并赋值给 AbstractBeanDefinitionfactoryBeanName属性。

  • 如你对本文有疑问或本文有错误之处,欢迎评论留言指出。如觉得本文对你有所帮助,欢迎点赞和关注。
相关文章
|
27天前
|
XML Java 数据格式
Spring从入门到入土(xml配置文件的基础使用方式)
本文详细介绍了Spring框架中XML配置文件的使用方法,包括读取配置文件、创建带参数的构造对象、使用工厂方法和静态方法创建对象、对象生命周期管理以及单例和多例模式的测试。
72 7
Spring从入门到入土(xml配置文件的基础使用方式)
|
8天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
30天前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
52 1
|
24天前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
|
24天前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
1月前
|
XML JavaScript Java
java与XML文件的读写
java与XML文件的读写
21 3
|
1月前
|
设计模式 JavaScript Java
Spring 事件监听机制源码
Spring 提供了事件发布订阅机制,广泛应用于项目中。本文介绍了如何通过自定义事件类、订阅类和发布类实现这一机制,并展示了如何监听 SpringBoot 启动过程中的多个事件(如 `ApplicationStartingEvent`、`ApplicationEnvironmentPreparedEvent` 等)。通过掌握这些事件,可以更好地理解 SpringBoot 的启动流程。示例代码展示了从事件发布到接收的完整过程。
|
1月前
|
缓存 Java Spring
源码解读:Spring如何解决构造器注入的循环依赖?
本文详细探讨了Spring框架中的循环依赖问题,包括构造器注入和字段注入两种情况,并重点分析了构造器注入循环依赖的解决方案。文章通过具体示例展示了循环依赖的错误信息及常见场景,提出了三种解决方法:重构代码、使用字段依赖注入以及使用`@Lazy`注解。其中,`@Lazy`注解通过延迟初始化和动态代理机制有效解决了循环依赖问题。作者建议优先使用`@Lazy`注解,并提供了详细的源码解析和调试截图,帮助读者深入理解其实现机制。
20 1
|
25天前
|
XML Java 数据格式
手动开发-简单的Spring基于注解配置的程序--源码解析
手动开发-简单的Spring基于注解配置的程序--源码解析
40 0
|
25天前
|
XML Java 数据格式
手动开发-简单的Spring基于XML配置的程序--源码解析
手动开发-简单的Spring基于XML配置的程序--源码解析
72 0