Spring之旅 - 记录学习 Spring 框架的过程和经验(二)基于Xml方式Bean的配置

前言

在现代 Java 开发中,Spring 框架以其强大的依赖注入和控制反转功能,成为了企业级应用开发的主要选择之一。Spring 支持多种方式进行 Bean 的配置,其中基于 XML 的配置方式是最早也是最经典的方式之一。尽管近年来注解和 Java 配置逐渐流行,但 XML 配置依然在许多项目中被广泛使用,尤其是在需要清晰可视化的配置场景下。

本文将深入探讨基于 XML 的 Bean 配置,包括如何定义、配置和管理 Spring Bean。同时,我们还会讨论 XML 配置的优缺点以及实际应用中的注意事项,以帮助开发者更好地理解和使用这一配置方式。


基于Xml方式的Spring应用

SpringBean的配置详解

Spring开发中主要是对Bean的配置,Bean的常用配置一览如下:

(1) Bean的基础配置例如:配置UserDaolmpl由Spring容器负责管理

xml 复制代码
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>

此时存储到Spring容器(singleObjects单例池)中的Bean的beanName是userDao,值是UserDaolmpl对象,可以根据beanName获取Bean实例

java 复制代码
applicationContext.getBean("userDao");

如果不配置id,则Spring会把当前Bean实例的全限定名作为beanName

java 复制代码
applicationContext.getBean ("com.itheima.dao.impl.UserDaoImpl");

(2)Bean的别名设置

可以为当前Bean指定多个别名,根据别名也可以获得Bean对象

java 复制代码
<bean id-"userDao" name-"aaa, bbb" class="com.itheima.dao.impl.UserDaoImpl"/>

此时多个名称都可以获得UserDaolmpl实例对象

java 复制代码
applicationContext.getBean("userDao");
applicationContext.getBean("aaa");
applicationContext.getBean("bbb");

(3)Bean的范围配置

默认情况下,单纯的Spring环境Bean的作用范围有两个:Singleton和Prototype

  • singleton:单例,默认值,Spring容器创建的时候,就会进行Bean的实例化,并存储到容器内部的单例池中,每次getBean时都是从单例池中获取相同的Bean实例;
  • prototype:原型,Spring容器初始化时不会创建Bean实例,当调用getBean时才会实例化Bean,每次getBean都会创建一个新的Bean实例。

(4)Bean的延迟加载

当lazy-init设置为true时为延迟加载,也就是当Spring容器创建的时候,不会立即创建Bean实例,等待用到时在创建Bean实例并存储到单例池中去,后续在使用该Bean直接从单例池获取即可,本质上该Bean还是单例的。

xml 复制代码
<bean id="userDao"class="com.itheima.dao.impl.UserDaoImpl" lazy-init="true"/>

(5)Bean的初始化和销毁方法配置

Bean在被实例化后,可以执行指定的初始化方法完成一些初始化的操作,Bean在销毁之前也可以执行指定的销毁方法完成一些操作,初始化方法名称和销毁方法名称通过。

xml 复制代码
<bean id-"userDao" class="com.itheima.dao.impl.UserDaoImpl" init-method="init"
destroy-method="destroy"/>
java 复制代码
package com.itheima.service.impl;

import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;
import com.itheima.service.UserService;

public class UserServiceImpl implements UserService {

    public UserServiceImpl(){
        System.out.println("UserServiceImpl实例化");
    }
    public void init(){
        System.out.println("初始化方法");
    }
    public void destroy(){
        System.out.println("销毁方法");
    }

}

测试代码:

java 复制代码
	public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService =(UserService) applicationContext.getBean("userService");
        System.out.println(userService);
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        classPathXmlApplicationContext.close();

    }

运行结果:

扩展:除此之外,我们还可以通过实现InitializingBean接口,完成一些Bean的初始化操作,如下:

java 复制代码
public class UserServiceImpl implements UserService , InitializingBean {

    ....

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet执行");
    }
}

测试代码:

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

    }

运行结果:

(6)Bean的实例化配置

Spring的实例化方式主要如下两种:

  • 构造方式实例化:底层通过构造方法对Bean进行实例化
  • 工厂方式实例化:底层通过调用自定义的工厂方法对Bean进行实例化

构造方式实例化Bean又分为无参构造方法实例化和有参构造方法实例化,Spring中配置的几乎都是无参构造该方式,此处不在赘述。下面讲解有参构造方法实例化Bean。

java 复制代码
public UserServiceImpl(String name){
       
}

有参构造在实例化Bean时,需要参数的注入,通过标签,嵌入在标签内部提供构造参数,如下:

java 复制代码
	<bean id="userService" class="com.itheima.service.impl.UserServiceImpl" >
        <property name="userDao" ref="userDao"></property>
        <constructor-arg name="name" value="hello"></constructor-arg>
    </bean>

工厂方式实例化Bean,又分为如下三种:

  • 静态工厂方法实例化Bean
  • 实例工厂方法实例化Bean
  • 实现FactoryBean规范延迟实例化Bean
java 复制代码
package com.itheima.factory;

import com.itheima.dao.UserDao;
import com.itheima.dao.impl.UserDaoImpl;

public class MyBeanFactory1 {
    public static UserDao userDao(){
        return new UserDaoImpl();
    }
}
xml 复制代码
<bean id="userDao1" class="com.itheima.factory.MyBeanFactory1" factory-method="userDao"></bean>
java 复制代码
public class MyBeanFactory2 {
    public  UserDao userDao(){
        return new UserDaoImpl();
    }
}
xml 复制代码
	<!--配置工厂对象 -->
    <bean id = "myBeanFactory2" class="com.itheima.factory.MyBeanFactory2"></bean>
    <bean id = "userDao2" factory-bean="myBeanFactory2" factory-method="userDao"></bean>
java 复制代码
public class MyBeanFactory1 {
    public static UserDao userDao(String name,int age){
        return new UserDaoImpl();
    }
}
xml 复制代码
	<bean id="userDao1" class="com.itheima.factory.MyBeanFactory1" factory-method="userDao">
        <constructor-arg name="name" value="hello"></constructor-arg>
        <constructor-arg name="age" value="18"></constructor-arg>
    </bean>
java 复制代码
public class MyBeanFactory2 {
    public  UserDao userDao(String name){
        return new UserDaoImpl();
    }
}
xml 复制代码
<!--配置工厂对象 -->
    <bean id = "myBeanFactory2" class="com.itheima.factory.MyBeanFactory2"></bean>
    <bean id = "userDao2" factory-bean="myBeanFactory2" factory-method="userDao">
        <constructor-arg name = "name" value="world"></constructor-arg>
    </bean>
java 复制代码
public class MyBeanFactory3 implements FactoryBean<UserDao> {

    @Nullable
    @Override
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    @Nullable
    @Override
    public Class<?> getObjectType() {
        return UserDao.class;
    }
}
xml 复制代码
<bean id="userDao3" class = "com.itheima.factory.MyBeanFactory3"></bean>

总结

基于 XML 的 Bean 配置方式在 Spring 框架中扮演着重要角色,虽然它面临着一些局限,但凭借其清晰性、灵活性和解耦性,依然在许多场景下具有不可替代的优势。了解 XML 配置的特点和使用场景,将帮助开发者在实际项目中做出更明智的选择。在不断变化的开发环境中,合理利用 XML 配置,将为构建高效、可维护的应用奠定坚实的基础。

相关推荐
L1624762 小时前
Redis 删除缓存全场景操作手册(详细版)
redis·spring·缓存
廋到被风吹走12 小时前
【Spring】DispatcherServlet解析
java·后端·spring
廋到被风吹走12 小时前
【Spring】PlatformTransactionManager详解
java·spring·wpf
それども13 小时前
Spring Bean 的name可以相同吗
java·后端·spring
qq_124987075315 小时前
基于微信小程序的电子元器件商城(源码+论文+部署+安装)
java·spring boot·spring·微信小程序·小程序·毕业设计
程序员阿鹏16 小时前
责任链模式
java·spring·servlet·tomcat·maven·责任链模式
黄俊懿17 小时前
【深入理解SpringCloud微服务】Seata(AT模式)源码解析——全局事务的回滚
java·后端·spring·spring cloud·微服务·架构·架构师
关于不上作者榜就原神启动那件事17 小时前
Spring Data Redis 中的 opsFor 方法详解
java·redis·spring
码农小卡拉20 小时前
Java多线程:CompletableFuture使用详解(超详细)
java·开发语言·spring boot·python·spring·spring cloud