[Spring Framework]bean的实例化

简介: bean的实例化

@[TOC]

bean的实例化

==bean本质上就是对象,对象在new的时候会使用构造方法完成,那创建bean也是使用构造方法完成的。==

接下来我们来说说Spring的IOC实例化对象的三种方式:

  • 构造方法(常用)
  • 静态工厂(了解)
  • 实例工厂(了解)

    • FactoryBean(实用)

构造方法

在这里插入图片描述

Spring底层用的是反射,因为这个构造函数无论是public还是private都可以被执行!

==一定要有一个空参构造器==

因为每一个类默认都会提供一个无参构造函数,所以其实真正在使用这种方式的时候,我们什么也不需要做。这也是我们以后比较常用的一种方式。

构造方法在类中默认会提供,但是如果重写了构造方法,默认的就会消失,在使用的过程中需要注意,如果需要重写构造方法,最好把默认的构造方法也重写下。

静态工厂

==首先我们来回顾一下使用工厂来创建对象。==

(1)准备一个OrderDao和OrderDaoImpl类

public interface OrderDao {
    public void save();
}

public class OrderDaoImpl implements OrderDao {
    public void save() {
        System.out.println("order dao save ...");
    }
}

(2)创建一个工厂类OrderDaoFactory并提供一个==静态方法==

//静态工厂创建对象
public class OrderDaoFactory {
    public static OrderDao getOrderDao(){
        return new OrderDaoImpl();
    }
}

(3)编写AppForInstanceOrder运行类,在类中通过工厂获取对象

public class AppForInstanceOrder {
    public static void main(String[] args) {
        //通过静态工厂创建对象
        OrderDao orderDao = OrderDaoFactory.getOrderDao();
        orderDao.save();
    }
}

(4)运行后,可以查看到结果
在这里插入图片描述
如果代码中对象是通过上面的这种方式来创建的,如何将其交给Spring来管理呢?

这就要用到Spring中的静态工厂实例化的知识了,具体实现步骤为:

步骤①:在spring的配置文件application.properties中添加以下内容:

<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>

class:工厂类的类全名

factory-mehod:具体工厂类中创建对象的方法名

对应关系如下图:
在这里插入图片描述
步骤②:在AppForInstanceOrder运行类,使用从IOC容器中获取bean的方法进行运行测试

public class AppForInstanceOrder {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");

        orderDao.save();

    }
}

步骤③:运行后,可以查看到结果
在这里插入图片描述

静态工厂的代码更加复杂,那么这么做的意义是什么?
在工厂的静态方法中,我们除了new对象还可以做其他的一些业务操作,这些操作必不可少,如:
在这里插入图片描述
之前new对象的方式就无法添加其他的业务内容

这种方式一般是用来兼容早期的一些老系统,所以==了解为主==:
在这里插入图片描述

实例工厂

我们还是先回顾一下如何使用实例工厂创建对象

(1)准备一个UserDao和UserDaoImpl类

public interface UserDao {
    public void save();
}

public class UserDaoImpl implements UserDao {

    public void save() {
        System.out.println("user dao save ...");
    }
}

(2)创建一个工厂类OrderDaoFactory并提供一个普通方法,==注意此处和静态工厂的工厂类不一样的地方是方法不是静态方法==

public class UserDaoFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

(3)编写AppForInstanceUser运行类,在类中通过工厂获取对象

public class AppForInstanceUser {
    public static void main(String[] args) {
        //创建实例工厂对象
        UserDaoFactory userDaoFactory = new UserDaoFactory();
        //通过实例工厂对象创建对象
        UserDao userDao = userDaoFactory.getUserDao();
        userDao.save();
}

(4)运行后,可以查看到结果
在这里插入图片描述

那么我们在spring中如何去实现呢?

步骤①:在spring的配置文件中添加以下内容:

<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>

实例化工厂运行的顺序是:

  • 创建实例化工厂对象,对应的是第一行配置
  • 调用对象中的方法来创建bean,对应的是第二行配置

    • factory-bean:工厂的实例对象
    • factory-method:工厂对象中的具体创建对象的方法名,对应关系如下:

在这里插入图片描述

步骤②:在AppForInstanceUser运行类,使用从IOC容器中获取bean的方法进行运行测试

public class AppForInstanceUser {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) ctx.getBean("userDao");
        userDao.save();
    }
}

在这里插入图片描述

FactoryBean的使用

FactoryBean方法严格来说属于实例工厂方法的改良延深

我们从实例工厂的方法中可以看出配置非常的麻烦,所以Spring为了简化这种配置方式就提供了一种叫FactoryBean的方式来简化开发。

我们借用前面的bookDao:
BookDao接口:

public interface BookDao {
    public void save();
}

bookDao实现类:

public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
}

接下来我们使用FactoryBean来对他进行实例化。

步骤①:首先我们直接创造一个对应的工厂类,这个工厂类要实现FactoryBean<>(带泛型),并且重写其中的几个方法:

public class BookServiceFactoryBean implements FactoryBean<BookService> {
    public BookService getObject() throws Exception {
        return new BookServiceImpl();
    }

    public Class<?> getObjectType() {
        return BookService.class;
    }

    public boolean isSingleton() {
        return false;
    }
}

方法一:getObject(),被重写后,在方法中进行对象的创建并返回

方法二:getObjectType(),被重写后,主要返回的是被创建类的Class对象

方法三:可以不去主动重写,因为它已经给了默认值,从方法名中可以看出其作用是设置对象是否为单例,默认true。(也就是说你不重写默认就是单例模式,如果不想单例模式就如上代码一样返回false)

步骤②:在Spring的配置文件中添加如下代码:

<bean id="bookService" class="factory.BookServiceFactoryBean"/>

也就是说容器中直接放工厂bean

接下来我们执行一下代码:

public class App2 {
    public static void main(String[] args) {
        //获取容器
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookService bookService = (BookService) ctx.getBean("bookService");    
        bookService.save();
    }
}

结果:

在这里插入图片描述

然后我们验证他是否为单例:

public class App2 {
    public static void main(String[] args) {
        //获取容器
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookService bookService1 = (BookService) ctx.getBean("bookService");
        BookService bookService2 = (BookService) ctx.getBean("bookService");

//        bookService.save();

        System.out.println(bookService1);
        System.out.println(bookService2);
    }
}

结果:
在这里插入图片描述

相关文章
|
4月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
20天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
2月前
|
XML Java 数据格式
Spring从入门到入土(bean的一些子标签及注解的使用)
本文详细介绍了Spring框架中Bean的创建和使用,包括使用XML配置文件中的标签和注解来创建和管理Bean,以及如何通过构造器、Setter方法和属性注入来配置Bean。
74 9
Spring从入门到入土(bean的一些子标签及注解的使用)
|
3月前
|
缓存 安全 Java
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
从底层源码入手,通过代码示例,追踪AnnotationConfigApplicationContext加载配置类、启动Spring容器的整个流程,并对IOC、BeanDefinition、PostProcesser等相关概念进行解释
232 24
Spring框架中Bean是如何加载的?从底层源码入手,详细解读Bean的创建流程
|
2月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
3月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
227 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
3月前
|
XML Java 数据格式
spring复习02,xml配置管理bean
详细讲解了Spring框架中基于XML配置文件管理bean的各种方式,包括获取bean、依赖注入、特殊值处理、属性赋值、集合类型处理、p命名空间、bean作用域及生命周期和自动装配。
spring复习02,xml配置管理bean
|
2月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
93 1
|
2月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
45 1
|
2月前
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细介绍了Spring框架中的核心概念——Spring Bean的生命周期,包括实例化、属性赋值、接口回调、初始化、使用及销毁等10个阶段,并深入剖析了相关源码,如`BeanFactory`、`DefaultListableBeanFactory`和`BeanPostProcessor`等关键类与接口。通过理解这些核心组件,读者可以更好地掌握Spring Bean的管理和控制机制。
92 1