Spring Bean创建方式
1. 基于 XML 配置声明的 Bean(传统方式)
这是 Spring 早期版本的配置方式,虽然现在较少用,但在遗留项目中很常见。
-
声明方式 :在
applicationContext.xml文件中使用<bean>标签。 -
特点:
-
定义明确:所有配置集中在一个文件中,结构清晰。
-
代码侵入性低:业务类本身无需任何 Spring 注解,是纯粹的 POJO。
-
繁琐:项目庞大时,XML 文件会变得非常臃肿,难以维护。
-
-
示例:
XML
<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 -->
<bean id="userService" class="com.example.service.UserServiceImpl">
<!-- 属性注入 -->
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>
</beans>
2. 基于注解声明的 Bean(现代主流方式)
这是目前最主流的 Bean 定义方式,利用注解来简化配置。
核心注解
-
@Component:通用注解,标识一个类为 Spring 组件(Bean)。 -
@Repository:用于 数据访问层(DAO) 的组件,是@Component的特殊化。除了组件扫描,它还负责将数据访问异常转换为 Spring 的统一DataAccessException。 -
@Service:用于 业务逻辑层(Service) 的组件,是@Component的特殊化。主要在语义上区分业务层。 -
@Controller/@RestController:用于 Web 控制层 的组件,是@Component的特殊化。@RestController是@Controller和@ResponseBody的组合,专用于 REST API。
3. Java 配置类与 @Bean
这是一种更灵活、更强大的编程式配置方式 ,常用于配置第三方库的组件 或 需要复杂初始化逻辑的 Bean。
-
@Configuration:标记一个类为配置类,相当于一个 XML 配置文件。 -
@Bean:在配置类的方法上使用,方法的返回值将被注册为 Spring 容器中的一个 Bean。方法名默认作为 Bean 的名称。
java
@Configuration
public class AppConfig {
@Bean // 方法返回的对象将成为一个名为"dataSource"的Bean
public DataSource dataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/mydb");
ds.setUsername("root");
ds.setPassword("password");
return ds;
}
@Bean
public UserService userService() {
// 可以在此方法中调用其他@Bean方法,进行依赖注入
return new UserServiceImpl(userDao());
}
@Bean
public UserDao userDao() {
return new UserDaoImpl(dataSource()); // 注入dataSource
}
}
| 类型 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|
| XML 配置 | 配置集中,与代码完全解耦,无需修改源码。 | 配置繁琐,类型不安全(编译时无法检查),重构困难。 | 老项目维护,或需要在不修改代码的情况下动态切换实现类。 |
| 注解扫描 | 配置简单,代码直观,类型安全,与业务逻辑紧密结合。 | 代码有一定侵入性,配置分散在各个类中。 | 现代 Spring Boot 项目的首选,适用于自己编写的业务组件。 |
@Bean 方法 |
灵活性极高,可以编程式控制 Bean 的创建过程,适合集成外部库。 | 配置相对复杂,需要编写额外的 Java 类。 | 配置数据源、线程池、第三方框架的客户端 等无法直接加 @Component 注解的组件。 |
Spring Bean作用域
-
singleton(默认):容器中只存在一个实例。 -
prototype:每次请求(获取)都创建一个新实例。 -
request:每次 HTTP 请求创建一个实例(仅 Web 环境)。 -
session:每个 HTTP Session 创建一个实例(仅 Web 环境)。 -
application:每个 ServletContext 生命周期内一个实例(仅 Web 环境)。 -
websocket:每个 WebSocket 会话一个实例。
Spring Bean初始化方式
-
预初始化(Eager) :容器启动时就创建(
singletonBean 默认)。 -
懒初始化(Lazy) :第一次被请求时才创建(使用
@Lazy注解)。