Spring之旅 - 记录学习 Spring 框架的过程和经验(四)Spring的get方法、Spring配置非定义的Bean、Bean实例化的基本流程

前言

在现代的 Java 开发中,Spring 框架因其灵活性和广泛的功能而备受欢迎。作为一个轻量级的容器,Spring 通过丰富的特性来管理对象的生命周期、依赖关系和配置。理解 Spring 的 get 方法、如何配置非定义的 Bean,以及 Bean 实例化的基本流程,对于开发者深入掌握 Spring 框架至关重要。

本博客将深入探讨 Spring 框架中的 get 方法的使用、如何通过配置创建非定义的 Bean 以及 Bean 实例化的过程。通过这些内容,您将能够更好地理解 Spring 的内部工作原理,并在实际项目中高效地使用 Spring 提供的各种功能。


Spring的get方法

java 复制代码
//根据beanName获取容器中的Bean实例,需要手动强转
UserService userservice - (Userservice) applicationContext.getBean("userservice");
//根据Bean类型去容器中匹配对应的Bean实例,如存在多个匹配Bean则报错
UserService userService2 = applicationContext.getBean(UserService.class);
//根据beanName获取容器中的Bean实例,指定Bean的Type类型
UserService userService3 = applicationContext.getBean ("userService",UserService.class);

Spring配置非定义的Bean

以上在xml中配置的Bean都是自己定义的,例如:UserDaolmpl,UserServicelmpl。但是,在实际开发中有些功能类并不是我们自己定义的,而是使用的第三方jar包中的,那么,这些Bean要想让Spring进行管理,也需要对其进行配置

配置非自定义的Bean需要考虑如下两个问题:

  • 被配置的Bean的实例化方式是什么?无参构造、有参构造、静态工厂方式还是实例工厂方式;
  • 被配置的Bean是否需要注入必要属性。

配置Druid数据源交由Spring管理导入Druid坐标

xml 复制代码
<!--mysql驱动 -->
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.49</version>
</dependency>
<!--druid数据源 -->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>druid</artifactId>
	<version>1.1.23</version>
</dependency>
xml 复制代码
<?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
                ">
   .....
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

</beans>

测试代码:

java 复制代码
public class ApplicationContextTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object dataSource = applicationContext.getBean("dataSource");
        System.out.println(dataSource);
    }
}

运行结果:

配置Connection交由Spring管理

Connection的产生是通过DriverManager的静态方法getConnection获取的,所以我们要用静态工厂方式配置

xml 复制代码
<bean class="java.lang.Class" factory-method="forName">
	<constructor-arg name="className" value="com.mysql.jdbc.Driver" />
</bean>
<bean id="connection" class="java. sql.DriverManager" factory-method="getConnection"
scope="prototype">
	<constructor-arg name="url" value="jdbc:mysql:///test"/>		
	<constructor-arg name="user" value="root"/><constructor-arg name="password" value="root"/>
</bean>

配置日期对象交由Spring管理

产生一个指定日期格式的对象,原始代码按如下:

java 复制代码
String currentTimeStr = "2024-12-05 09:00:30";
SimpleDateFormat simpleDaterFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(currentrimeStr);

可以看成是实例工厂方式,使用Spring配置方式产生Date实例

xml 复制代码
<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">	
	<constructor-arg name="pattern" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
<bean id="date" factory-bean="simpleDateFormat" factory-method="parse")
	<constructor-arg name="source" value="2023-08-27 07:20:00"/>
</bean>

配置MyBatis的SqlSessionFactory交由Spring管理

导入MyBatis的相关坐标:

xml 复制代码
<!--mybatis框架-->
<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.5.5</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
	<groupId>nysgl</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.49</version>
</dependency>

创建mybatis-config.xml文件

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
</configuration>
xml 复制代码
	<!--静态工厂方法方式-->
    <bean id="in" class="org.apache.ibatis.io.Resources" factory-method="getResourceAsStream">
        <constructor-arg name = "resource" value="mybatis-config.xml"></constructor-arg>
    </bean>
    <!--静无参构造实例化-->
    <bean id="builder" class="org.apache.ibatis.session.SqlSessionFactoryBuilder"></bean>
    <!--实例工厂方法-->
    <bean id="sqlSessionFactory" factory-bean="builder" factory-method="build">
        <constructor-arg name="inputStream" ref="in" ></constructor-arg>
    </bean>

测试代码:

java 复制代码
	public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        Object sqlSessionFactory = applicationContext.getBean("sqlSessionFactory");
        System.out.println(sqlSessionFactory);


    }

运行结果:

Bean实例化的基本流程

Spring容器在进行初始化时,会将xml配置的< bean>的信息封装成一个BeanDefinition对象,所有的BeanDefinition存储到一个名为beanDefinitionMap的Map集合中去,Spring框架在对该Map进行遍历,使用反射创建Bean实例对象,创建好的Bean对象存储在一个名为singletonObjects的Map集合中,当调用getBean方法时则最终从该Map集合中取出Bean实例对象返回。

Bean信息定义对象-BeanDefinition

-Bean实例化的基本流程

  • 加载xml配置文件,解析获取配置中的每个的信息,封装成一个个的BeanDefinition对象;
  • 将BeanDefinition存储在一个名为beanDefinitionMap的Map<String,BeanDefinition>中;
  • ApplicationContext底层遍历beanDefinitionMap,创建Bean实例对象;
  • 创建好的Bean实例对象,被存储到一个名为singletonObjects的Map<String,Object>中;
  • 当执行applicationContext.getBean(beanName)时,从singletonObjects去匹配Bean实例返回。

总结

在本文中,我们探讨了 Spring 框架中 get 方法的使用,如何配置非定义的 Bean,以及 Bean 实例化的基本流程。这些内容对于理解 Spring 容器的工作原理和有效利用 Spring 提供的功能至关重要。

通过掌握 Spring 的 get 方法,您可以灵活地获取 Bean 实例;通过配置非定义的 Bean,您可以根据业务需求动态创建和管理 Bean;而了解 Bean 实例化的流程,则能帮助您更深刻地理解 Spring 的内部机制。

希望这篇博客能帮助您更好地理解 Spring 框架的核心概念和应用。如果您有任何问题或想要进一步讨论的话题,请随时留言!

相关推荐
开开心心_Every2 小时前
定时管理进程:防止沉迷电脑的软件推荐
xml·java·运维·服务器·网络·数据库·excel
Nan_Shu_6142 小时前
学习:TypeScript (1)
前端·javascript·学习·typescript
海清河晏1112 小时前
Linux进阶篇:深入理解线程
java·jvm·算法
2301_797312262 小时前
学习Java32天
java·开发语言
Mr.朱鹏2 小时前
分布式接口幂等性实战指南【完整版】
java·spring boot·分布式·sql·spring·云原生·幂等
TAEHENGV2 小时前
提醒列表模块 Cordova 与 OpenHarmony 混合开发实战
android·java·harmonyos
崇山峻岭之间2 小时前
Matlab学习记录13
开发语言·学习·matlab
源码获取_wx:Fegn08952 小时前
基于springboot + vue宠物寄养系统
java·vue.js·spring boot·后端·spring·宠物
Coder_Boy_2 小时前
SpringAI与LangChain4j的智能应用-(理论篇)
人工智能·spring·mybatis·springai·langchain4j