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 框架的核心概念和应用。如果您有任何问题或想要进一步讨论的话题,请随时留言!

相关推荐
小希smallxi11 小时前
Java 程序调用 FFmpeg 教程
java·python·ffmpeg
李慕婉学姐11 小时前
【开题答辩过程】以《基于Java的周边游优选推荐网站的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言
儒雅永缘11 小时前
Solidworks练习39-拉伸、拉伸切
笔记·学习
来两个炸鸡腿11 小时前
【Datawhale组队学习202601】Base-NLP task01 注意力机制与Transformer
学习·自然语言处理·transformer
计算机毕设指导611 小时前
基于微信小程序民宿预订管理系统【源码文末联系】
java·spring boot·mysql·微信小程序·小程序·tomcat·maven
我命由我1234511 小时前
Kotlin 开发 - Kotlin Lambda 表达式返回值
android·java·开发语言·java-ee·kotlin·android studio·android-studio
Knight_AL11 小时前
从单例模式说起:Java 常见设计模式的理解与实践
java·单例模式·设计模式
am心11 小时前
学习笔记-缓存&添加购物车
笔记·学习·缓存
a努力。11 小时前
中国电网Java面试被问:Dubbo的服务目录和路由链实现
java·开发语言·jvm·后端·面试·职场和发展·dubbo
爬山算法11 小时前
Hibernate(42)在Hibernate中如何实现分页?
java·后端·hibernate