欢迎光临
我们一直在努力

深入Spring核心:工厂类、Bean生命周期与注解配置详解

        在Spring框架的学习中,控制反转(IOC)是基石。掌握了如何让Spring容器创建和管理对象后,我们需要更深入地了解容器本身、对象的生老病死,以及如何用更优雅的注解方式来简化配置。本文将带你从Spring的工厂类入手,逐步解析Bean的生命周期和作用域,并过渡到基于注解的IOP配置实践。


目录

一、Spring的工厂类:ApplicationContext 与 BeanFactory

1. ApplicationContext

2. BeanFactory

3. 核心区别与验证

二、Bean的作用域与生命周期

1. Bean的作用域(Scope)

2. Bean的生命周期

三、迈向注解:基于注解的IOC与DI配置

1. 开启注解扫描

2. 创建对象的注解(取代

)

3. 依赖注入的注解(取代

)

总结


一、Spring的工厂类:ApplicationContext 与 BeanFactory

        Spring提供了两种核心的容器(工厂)接口来创建和管理Bean:ApplicationContext和 BeanFactory。它们构成了IOC容器的基础,但在行为上有显著差异。

1. ApplicationContext

        ApplicationContext是 BeanFactory的子接口,提供了更多企业级功能。在创建容器时,它会立即加载并实例化所有配置的单例Bean,这种“急切加载”方式确保了应用启动后Bean立即可用。常见的实现类有:

ClassPathXmlApplicationContext 从类路径下加载XML配置文件。
FileSystemXmlApplicationContext 从文件系统路径加载XML配置文件

其类结构关系如下图所示:

2. BeanFactory

        BeanFactory是Spring容器最顶层的接口,提供了IOC的基础功能。与ApplicationContext的最大区别在于它的延迟加载机制:只有在首次通过getBean()方法请求某个Bean时,容器才会创建该Bean的实例。它的一个常用实现是XmlBeanFactory(注:Spring 5.x后已不推荐使用)。

3. 核心区别与验证

        我们可以通过一个简单的测试来观察二者的区别。假设我们有一个UserServiceImpl,在其无参构造方法中打印日志。

使用ApplicationContext:

public class Client {
public static void main(String[] args) {
new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("Spring IOC容器创建好了");
}
}

输出结果为:

Bean在容器初始化时就被创建。

使用BeanFactory:

public class Client {
public static void main(String[] args) {
new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
System.out.println("Spring IOC容器创建好了");
}
}

输出结果为:

此时Bean并未被创建,直到调用getBean(“userService”)时才会触发构造方法。

在实际开发中,功能更全面的ApplicationContext是更常见的选择。

二、Bean的作用域与生命周期

        理解Bean何时创建、如何存在以及何时销毁,是进行高效、正确开发的关键。

1. Bean的作用域(Scope)

通过<bean>标签的scope属性,我们可以控制Bean的实例范围,常用的有以下几种:

singleton (默认) 在整个IOC容器中,该Bean定义只存在一个共享实例。适合无状态的Service、DAO等
prototype 每次请求该Bean时都会创建一个新的实例。适合有状态的Connection、SqlSession等对象
request/session/application 专用于Web环境,将Bean生命周期绑定到对应的Http请求、会话或应用全局

配置示例:<bean id="userService" class="…" scope="prototype"/>

2. Bean的生命周期

Bean从创建到销毁的完整过程,对于单例和多例模式有所不同。

单例Bean的生命周期:

[容器启动] —> 构造方法(实例化) —> set方法(依赖注入) —> init方法(自定义初始化) —> [容器关闭] —> destroy方法(自定义销毁)

多例Bean的生命周期:

[调用getBean()] —> 构造方法(实例化) —> set方法(依赖注入) —> init方法(自定义初始化) —> [JVM垃圾回收] —> destroy方法(自定义销毁) (注意:Spring容器不管理原型Bean的销毁)

我们可以通过init-method和destroy-method属性指定自定义的初始化和销毁方法,让Spring在对应时机调用。

三、迈向注解:基于注解的IOC与DI配置

        XML配置功能强大但略显繁琐。Spring提供了基于注解的配置方式,其目标与XML完全一致——降低耦合,只是形式更简洁,贴近代码。

1. 开启注解扫描

首先,需要在XML配置中声明注解驱动,并指定要扫描的包。Spring会自动扫描该包及其子包下的类,识别特定注解。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
…>
<!– 开启注解扫描,base-package指定扫描的根包 –>
<context:component-scan base-package="com.hg"></context:component-scan>
</beans>

2. 创建对象的注解(取代 <bean>)

以下四个注解功能相同,都用于将类声明为Spring管理的Bean,主要提供语义化区分:

@Component 通用注解,用于任何组件
@Controller 通常用于标注表现层(如MVC控制器)组件
@Service 通常用于标注业务逻辑层组件
@Repository 通常用于标注数据访问层(DAO)组件

属性value用于指定Bean在容器中的id。若不指定,则默认id为类名首字母小写。

//@Service("userService") 自定义id为"userService"
@Service // 默认id为"userServiceImpl"
public class UserServiceImpl implements UserService { … }

@Repository // 默认id为"userDaoImpl"
public class UserDaoImpl implements UserDao { … }

3. 依赖注入的注解(取代 <property>)

@Autowired(Spring提供) 默认按类型(byType)自动装配。可以与@Qualifier结合使用,实现按名称装配
@Resource(JSR-250标准) 默认按名称(byName)自动装配。可通过name属性显式指定Bean的id

@Service
public class UserServiceImpl implements UserService {
@Autowired // 按类型查找UserDao的实现类并注入
private UserDao userDao;
// 或者
@Resource(name="userDaoImpl") // 按名称查找id为"userDaoImpl"的Bean并注入
private UserDao userDao;

}

@Value 用于注入基本数据类型和String类型的值。可以直接注入字面量,也支持从属性文件(.properties)中读取,极大提升了配置的灵活性

① 注入简单值:

@Service
public class UserServiceImpl implements UserService {
@Value("张三")
private String name;
@Value("25")
private Integer age;
}

② 注入属性文件中的值:

首先,在XML中加载属性文件:

<context:property-placeholder location="config.properties"/>

然后,在属性文件config.properties中定义:

jdbc.username=root
jdbc.password=123456

最后,在类中使用@Value并配合${}占位符注入:

@Service
public class UserServiceImpl implements UserService {
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
}


总结

        从理解ApplicationContext和BeanFactory这两大容器的加载机制差异,到掌握Bean的singleton与prototype作用域及其完整的生命周期,是夯实Spring IOC核心概念的关键。而基于注解的配置方式(@Component, @Autowired, @Value等)则代表了更现代、更简洁的Spring开发风格,它通过将配置信息直接写在代码中,减少了XML文件的维护成本,提高了开发效率。从XML到注解,是Spring学习者必须跨越的一道桥梁。

赞(0)
未经允许不得转载:171主机测评 » 深入Spring核心:工厂类、Bean生命周期与注解配置详解
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址