XML方式配置Spring容器
XML方式配置Spring容器
核心步骤
-
导入依赖
-
创建Spring配置文件
- 虽然没有严格的命名规则,通常使用
applicationContext.xml作为默认的Spring配置文件名称。
- 虽然没有严格的命名规则,通常使用
-
定义Bean
-
配置Bean的依赖
-
如果需要使用AOP(面向切面编程),可以在XML配置文件中定义切面、切点和通知
-
如果需要使用Spring的事务管理,可以在XML配置文件中定义事务管理器及其相关配置
-
加载Spring配置文件
-
在Java代码中,使用
ClassPathXmlApplicationContext或FileSystemXmlApplicationContext加载Spring配置文件并初始化Spring容器 -
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //根据id获取Bean MyBean myBean = (MyBean) context.getBean("myBean"); //根据类型获取Bean MyBean myBean = (MyBean) context.getBean(MyBean.class); //根据id和类型获取Bean MyBean myBean = (MyBean) context.getBean("myBean",MyBean.class); myBean.doSomething(); } }
-
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">
</beans>
一个基础的Spring XML配置文件通常包含以下部分:
- XML声明:指定XML版本和编码。
- Spring命名空间:引入Spring的命名空间(如
beans、context等)。 - Bean定义:定义Spring容器管理的Bean。
- 依赖注入:通过构造函数或setter方法注入依赖。
- 注解支持:启用注解扫描,简化配置。
- 引用外部文件:使用
${}占位符引用文件中的属性
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 加载外部属性文件 -->
<context:property-placeholder location="classpath:config.properties"/>
<!-- 启用注解扫描 -->
<context:component-scan base-package="com.example" />
<!-- 定义一个Bean -->
<bean id="myService" class="com.example.MyServiceImpl">
<!-- 注入依赖 -->
<property name="myRepository" ref="myRepository" />
</bean>
<!-- 定义另一个Bean -->
<bean id="myRepository" class="com.example.MyRepositoryImpl" />
</beans>
<context:component-scan> 元素
-
用于启用注解扫描,自动注册带有
@Component、@Service、@Repository、@Controller等注解的类。 -
base-package属性指定扫描的包路径。<context:component-scan base-package="com.example" />
<import> 元素
-
用于导入其他配置文件,实现模块化配置。
<import resource="applicationContext-dao.xml" /> <import resource="applicationContext-service.xml" />
配置文件中的元素
- 是所有Spring配置文件的根元素。
- 通过
xmlns引入Spring的命名空间。 - 通过
xsi:schemaLocation指定命名空间的Schema文件位置。
-
用于定义一个Bean。
-
<bean id="myBean" class="com.example.MyBean" scope="singleton" init-method="init" destroy-method="destroy" /> -
常用属性:
id:Bean的唯一标识符。class:Bean的全限定类名。scope:Bean的作用域(如singleton、prototype等)。- singleton(默认值):
- 作用: 单例模式。Spring容器中只会创建一个Bean实例,所有对该Bean的请求都会返回同一个实例。
- 在Bean实例创建并完成依赖注入后,Spring容器会立即调用
init-method指定的方法,仅调用一次,因为singletonBean在容器中只有一个实例 - 在Spring容器关闭时,Spring会调用
destroy-method指定的方法,仅调用一次,因为singletonBean在容器中只有一个实例 - 生命周期: Bean实例在Spring容器启动时创建,容器关闭时销毁。
- 适用场景: 适用于无状态的Bean,例如服务类、工具类等。
- prototype:
- 作用: 原型模式。每次请求Bean时,Spring容器都会创建一个新的实例。
- 每次创建新的Bean实例并完成依赖注入后,Spring容器会调用
init-method指定的方法,每次创建新实例时都会调用一次 - Spring容器不会管理
prototypeBean的生命周期,因此destroy-method指定的方法不会被自动调用,prototypeBean的生命周期由客户端代码管理,Spring容器只负责创建Bean实例,不负责销毁 - 生命周期: Bean实例在每次请求时创建,容器不管理其生命周期,即不会调用销毁方法。
- 适用场景: 适用于有状态的Bean,例如每次请求都需要独立状态的Bean。
- singleton(默认值):
init-method:指定Bean初始化时调用的方法。destroy-method:指定Bean销毁时调用的方法。
-
init-method-
作用: 指定Bean初始化完成后调用的方法。
-
调用时机: 在Bean的所有依赖注入完成之后,Bean实例已经创建并准备好使用时调用。
-
方法要求:
- 方法名由
init-method属性指定。 - 方法必须是无参的(即没有参数)。
- 方法可以是
public、protected或private(如果是private,Spring会通过反射调用)。 - 方法返回值类型必须是
void。
public class MyBean { public void init() { System.out.println("MyBean is initialized!"); } }<bean id="myBean" class="com.example.MyBean" init-method="init" /> - 方法名由
-
-
destroy-method-
作用: 指定Bean销毁前调用的方法。
-
调用时机: 在Spring容器关闭时,或者Bean的作用域结束(例如
singletonBean在容器关闭时,prototypeBean不会被调用)。 -
方法要求:
- 方法名由
destroy-method属性指定。 - 方法必须是无参的(即没有参数)。
- 方法可以是
public、protected或private(如果是private,Spring会通过反射调用)。 - 方法返回值类型必须是
void。
package com.example; public class MyBean { public void destroy() { System.out.println("MyBean destroyed!"); } }<bean id="myBean" class="com.example.MyBean" init-method="init" destroy-method="destroy" /> - 方法名由
-
依赖注入
Spring支持两种依赖注入方式:
Setter注入:
-
Setter注入是通过调用类的Setter方法来注入依赖项的一种方式。Spring容器会在创建Bean实例后,调用相应的Setter方法来注入依赖项。
-
必须要有对应的Setter方法
-
Setter注入只考虑一个参数的Setter方法就行,如果Setter方法有多个参数,通常意味着这些参数是紧密相关的,可以考虑使用构造器注入
-
通过
<property>标签注入依赖。
<bean id="myService" class="com.example.MyServiceImpl">
<property name="myRepository" ref="myRepository" />
</bean>
-
注入基本类型
中的name值为set方法去掉set并小写第一个字母 <bean id="userService" class="com.example.UserService"> <property name="maxUsers" value="100" /> </bean>public class UserService { private int maxUsers; public void setMaxUsers(int maxUsers) { this.maxUsers = maxUsers; } } -
注入集合类型
-
Spring支持注入集合类型,如
List、Set、Map等 -
List
<bean id="userService" class="com.example.UserService"> <property name="userNames"> <list> <value>Alice</value> <value>Bob</value> <value>Charlie</value> </list> </property> </bean> -
map
<bean id="userService" class="com.example.UserService"> <property name="userAges"> <map> <entry key="Alice" value="25" /> <entry key="Bob" value="30" /> <entry key="Charlie" value="35" /> </map> </property> </bean> -
set
<bean id="userService" class="com.example.UserService"> <property name="userRoles"> <set> <value>ADMIN</value> <value>USER</value> <value>GUEST</value> </set> </property> </bean>
-
-
注入自定义对象
-
使用
<ref>标签引用其他Bean -
<bean id="myService" class="com.example.MyServiceImpl"> <property name="myRepository" ref="myRepository" /> </bean>
-
-
注入集合中为自定义对象
-
List
-
<bean id="userService" class="com.example.UserService"> <property name="users"> <list> <ref bean="user1" /> <ref bean="user2" /> <ref bean="user3" /> </list> </property> </bean>
-
-
set
-
<bean id="userService" class="com.example.UserService"> <property name="users"> <set> <ref bean="user1" /> <ref bean="user2" /> <ref bean="user3" /> </set> </property> </bean>
-
-
map
-
<bean id="userService" class="com.example.UserService"> <property name="userMap"> <map> <entry key="user1" value-ref="user1" /> <entry key="user2" value-ref="user2" /> <entry key="user3" value-ref="user3" /> </map> </property> </bean>
-
-
构造函数注入:
通过<constructor-arg>标签注入依赖。
<bean id="myService" class="com.example.MyServiceImpl">
<constructor-arg ref="myRepository" />
</bean>
<constructor-arg>:定义构造函数参数:ref:引用其他Bean(用于注入其他Bean)。value:注入基本类型或字符串值。index:指定参数的位置(从0开始)。type:指定参数的类型(用于消除歧义)。
-
注入基本类型或字符串
- 使用
value属性注入基本类型或字符串值
<bean id="myService" class="com.example.MyService"> <constructor-arg value="42"/> <constructor-arg value="Hello, World!"/> </bean>public MyService(int number, String message) { this.number = number; this.message = message; } - 使用
-
使用
ref:引用其他Bean -
按照顺序注入
-
如果构造函数有多个参数,Spring会按照
<constructor-arg>的顺序匹配参数 -
<bean id="myService" class="com.example.MyService"> <constructor-arg ref="myRepository"/> <constructor-arg value="Hello, World!"/> </bean> -
public MyService(MyRepository repository, String message) { this.repository = repository; this.message = message; }
-
-
按照参数名称
-
可以通过
name属性指定参数名称,避免顺序问题。 -
<bean id="userService" class="com.example.UserService"> <constructor-arg name="message" value="Hello, World!"/> <constructor-arg name="repository" ref="myRepository"/> </bean>
-
-
按索引注入
-
如果参数顺序不明确,可以使用
index属性指定参数的位置 -
<bean id="myService" class="com.example.MyService"> <constructor-arg index="1" value="Hello, World!"/> <constructor-arg index="0" ref="myRepository"/> </bean>
-
-
按类型注入
-
如果参数类型不明确,可以使用
type属性指定参数的类型 -
<bean id="myService" class="com.example.MyService"> <constructor-arg type="com.example.MyRepository" ref="myRepository"/> <constructor-arg type="java.lang.String" value="Hello, World!"/> </bean>
-
-
注入集合
-
List
-
<bean id="myService" class="com.example.MyService"> <constructor-arg> <list> <value>Item 1</value> <value>Item 2</value> <value>Item 3</value> </list> </constructor-arg> </bean>
-
-
set
-
<bean id="myService" class="com.example.MyService"> <constructor-arg> <set> <value>Item 1</value> <value>Item 2</value> <value>Item 3</value> </set> </constructor-arg> </bean>
-
-
map
-
<bean id="myService" class="com.example.MyService"> <constructor-arg> <map> <entry key="Key1" value="10"/> <entry key="Key2" value="20"/> <entry key="Key3" value="30"/> </map> </constructor-arg> </bean>
-
-
注入
Properties类型-
<bean id="myService" class="com.example.MyService"> <constructor-arg> <props> <prop key="username">admin</prop> <prop key="password">123456</prop> </props> </constructor-arg> </bean>
-
-
注入特殊值
-
注入空值(null)
-
在 XML 中,使用
<null/>标签表示空值<bean id="userService" class="com.example.UserService"> <property name="username"> <null/> </property> </bean> -
在注解中,直接赋值为
null即可@Service public class UserService { private String username = null; // 直接赋值为 null // 其他逻辑 }
-
-
给数组注入值
-
XML
<bean id="user" class="pojo.User"> <property name="array"> <array> <value>1</value> <value>2</value> </array> </property> </bean>
-
-
注入对象
-
内部Bean
-
内部 Bean 注入是指在一个 Bean 的定义中嵌套定义另一个 Bean。内部 Bean 的作用域仅限于外部 Bean,不能被其他 Bean 引用
-
<bean id="userService" class="com.example.UserService"> <property name="userRepository"> <!-- 定义内部 Bean --> <bean class="com.example.UserRepository"/> </property> </bean> -
内部 Bean 没有
id属性-只被该外部Bean使用。 -
内部 Bean 的作用域仅限于
userService
-
-
-
可以引用外部对象后在使用级联赋值修改对象属性值
<bean id="address" class="pojo.Address"/> <bean id="user" class="pojo.User"> <property name="username" value="1"/> <property name="age" value="20"/> <property name="address" ref="address" /> <property name="address.id" value="11"/> <property name="address.name" value="12"/> </bean>

浙公网安备 33010602011771号