目录
- Spring Beans
- 模块详解
- 1. 什么是 Bean?
- 2. Spring Bean的配置方式
- 2.1 基于 XML 配置
- 例子:
- 2.2 基于注解配置
- 例子:
- 2.3 基于 Java 配置(JavaConfig)
- 例子:
- 3. Bean 的生命周期
- 生命周期回调的例子:
- 4. Bean 的作用域
- 例子:
- 5. 依赖注入方式
- 5.1 构造器注入
- 例子:
- 5.2 Setter 注入
- 例子:
- 5.3 字段注入
- 例子:
- 6. 自动装配(Autowiring)
- 例子:
- 7. Bean 的依赖关系
- 例子:
- 8. Bean 后置处理器(BeanPostProcessor)
- 例子:
- 总结
- Spring Context
- 1. 什么是 Spring Context?
- 2. ApplicationContext 的主要实现
- 3. 国际化支持
- 国际化消息文件
- 使用 `MessageSource`
- XML 配置:
- Java 配置:
- 使用国际化消息:
- 4. 事件处理机制
- 核心接口与类:
- 自定义事件:
- 自定义监听器:
- 发布事件:
- 5. 资源访问
- 获取资源:
- 6. 生命周期管理
- 生命周期回调:
- 生命周期回调示例:
- 7. Environment 抽象
- 访问环境属性:
- 8. ApplicationContext 的扩展
- WebApplicationContext 示例:
- 总结
Spring Beans
模块详解
Spring Beans 模块是 Spring 框架的核心部分之一,它主要负责 Bean(即应用程序中的对象)的定义、配置、创建、管理和销毁。Spring Beans 模块通过依赖注入(Dependency Injection, DI)和控制反转(Inversion of Control, IoC)模式帮助开发者解耦对象之间的依赖关系,从而简化代码结构,提高可测试性和可维护性。
1. 什么是 Bean?
在 Spring 中,Bean 是指由 Spring IoC 容器管理的对象。Bean 是 Spring 应用程序的基本构造单元,通过配置文件或注解方式定义,Spring 容器根据这些定义来实例化、配置和管理这些对象。Bean 可以是任何 Java 对象,不仅限于简单的 POJO(Plain Old Java Object),它可以是复杂的业务逻辑对象、数据访问对象、服务对象等。
2. Spring Bean的配置方式
Spring 支持多种方式来配置 Bean,包括基于 XML 配置、基于注解配置以及基于 Java 配置(JavaConfig)。以下分别介绍每种方式的用法。
2.1 基于 XML 配置
XML 是 Spring 传统的配置方式。通过 XML 文件,我们可以定义 Bean 的类、属性、构造器注入、作用域等信息。
例子:
<!-- XML 配置 Bean -->
<bean id="myBean" class="com.example.MyBean">
<!-- 使用 setter 方法注入 -->
<property name="name" value="Spring" />
</bean>
在这个例子中,Spring 容器会根据 XML 中的配置创建一个 com.example.MyBean
类的对象,并将 name
属性的值设置为 "Spring"
。
2.2 基于注解配置
基于注解的配置使用更为现代化,简化了 XML 配置的复杂性。开发者可以在 Java 类上直接使用注解来定义 Bean。
常见的注解有:
- @Component:用于标注一个类为 Spring Bean,通常与自动扫描(Component Scanning)结合使用。
- @Autowired:用于注入依赖,可以是字段注入、构造器注入或 setter 注入。
- @Service、@Repository、@Controller:这些注解是 @Component 的特化,用于表示具体的层次(服务层、数据访问层、控制器层)。
例子:
@Component
public class MyBean {
private String name = "Spring";
}
@Service
public class MyService {
@Autowired
private MyBean myBean;
}
在这个例子中,MyBean
被标记为一个组件(@Component
),并通过 @Autowired
注入到 MyService
类中。
2.3 基于 Java 配置(JavaConfig)
JavaConfig 是一种基于 Java 类的配置方式,开发者可以使用纯 Java 类来配置 Spring Bean。JavaConfig 通过标注配置类(@Configuration
)和 Bean 方法(@Bean
)来实现,避免了 XML 文件的使用。
例子:
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean();
}
@Bean
public MyService myService() {
return new MyService(myBean());
}
}
在这个例子中,AppConfig
是一个配置类,其中定义了两个 Bean(MyBean
和 MyService
)。Spring 容器会根据配置类创建这些 Bean 并管理它们的生命周期。
3. Bean 的生命周期
Spring 容器负责管理 Bean 的整个生命周期,包括它的创建、初始化、使用、销毁等过程。Bean 的生命周期可以通过以下阶段描述:
- 实例化:Spring 容器根据配置实例化 Bean 对象。
- 依赖注入:Spring 容器通过构造器注入或 setter 注入,将所需的依赖对象注入到 Bean 中。
- 初始化:如果 Bean 实现了
InitializingBean
接口或配置了init-method
,Spring 容器会在 Bean 初始化时调用对应的方法。 - 使用:Bean 被应用程序使用。
- 销毁:当容器关闭时,如果 Bean 实现了
DisposableBean
接口或配置了destroy-method
,Spring 容器会调用销毁方法。
生命周期回调的例子:
@Component
public class MyBean implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Bean 初始化");
}
@Override
public void destroy() throws Exception {
System.out.println("Bean 销毁");
}
}
4. Bean 的作用域
Spring 支持多种 Bean 的作用域,以控制 Bean 的生命周期和共享方式。常见的作用域包括:
- singleton(默认):容器中只有一个单实例的 Bean,所有对该 Bean 的请求都返回同一实例。
- prototype:每次请求时都会创建一个新的 Bean 实例。
- request:为每个 HTTP 请求创建一个新的 Bean 实例(仅用于 Web 应用)。
- session:为每个 HTTP 会话创建一个新的 Bean 实例(仅用于 Web 应用)。
- application:为整个 ServletContext 创建一个 Bean 实例(仅用于 Web 应用)。
例子:
<bean id="myBean" class="com.example.MyBean" scope="prototype"/>
在这个例子中,myBean
是一个 prototype
范围的 Bean,因此每次请求这个 Bean 时,Spring 都会创建一个新的实例。
5. 依赖注入方式
Spring 提供了多种依赖注入方式,主要包括以下几种:
5.1 构造器注入
构造器注入是在 Bean 实例化时通过构造器将依赖传入。
例子:
<bean id="myBean" class="com.example.MyBean">
<constructor-arg name="name" value="Spring" />
</bean>
5.2 Setter 注入
Setter 注入是在 Bean 实例化后,通过 Setter 方法将依赖注入。
例子:
<bean id="myBean" class="com.example.MyBean">
<property name="name" value="Spring" />
</bean>
5.3 字段注入
字段注入是使用 @Autowired
注解直接在类的字段上进行注入。这种方式不需要通过 Setter 方法或者构造器来实现注入。
例子:
@Component
public class MyService {
@Autowired
private MyBean myBean;
}
6. 自动装配(Autowiring)
Spring 提供了多种自动装配的方式,通过 @Autowired
注解或者 XML 配置,Spring 可以自动将依赖注入到所需的对象中。
自动装配的方式包括:
- byType:按类型自动装配 Bean。
- byName:按名称自动装配 Bean。
- constructor:通过构造器进行自动装配。
- autodetect:自动检测使用构造器注入或 setter 注入。
例子:
<bean id="myService" class="com.example.MyService" autowire="byType"/>
7. Bean 的依赖关系
Spring 支持通过配置来定义 Bean 之间的依赖关系。开发者可以在 XML 配置文件或 Java 配置类中显式指定某些 Bean 需要在其他 Bean 之前加载。
例子:
<bean id="beanA" class="com.example.BeanA"/>
<bean id="beanB" class="com.example.BeanB" depends-on="beanA"/>
在这个例子中,beanB
依赖于 beanA
,Spring 容器会先实例化 beanA
,再实例化 beanB
。
8. Bean 后置处理器(BeanPostProcessor)
BeanPostProcessor
是 Spring 提供的一个接口,允许开发者在 Bean 初始化之前和之后对 Bean 进行额外的处理。可以用于修改 Bean 实例或动态代理。
例子:
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("Before Initialization: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println("After Initialization: " + beanName);
return bean;
}
}
总结
Spring Beans 模块是 Spring 框架的核心模块,它负责对象的定义、配置、管理和生命周期处理。通过 IoC 和 DI 模式,Spring Beans 模块帮助开发者解耦对象间的依赖,简化了对象创建和管理
Spring Context
Spring Context 模块是 Spring 框架的一个重要模块,它建立在 Core 和 Beans 模块的基础之上,提供了更高级的特性,如国际化(I18N)、事件传播、资源管理、依赖注入(DI)、生命周期管理以及对 Java EE 特性的支持。它扩展了 BeanFactory
,为应用程序提供了丰富的上下文环境。
1. 什么是 Spring Context?
ApplicationContext
是 Spring Context 模块的核心接口,它是 Spring IoC 容器的高级接口,扩展了基础的 BeanFactory
功能,不仅支持 Bean 的创建和管理,还提供了企业级的特性,例如:
- 国际化(国际化消息)
- 事件传播(监听和发布事件)
- 资源访问(文件、URL、classpath 等)
- 自动装配(基于注解和自动检测)
通过 ApplicationContext
,Spring 应用程序能够管理 Bean 的生命周期、依赖关系、配置和运行时行为。
2. ApplicationContext 的主要实现
Spring 提供了多种 ApplicationContext
的实现,适用于不同的应用场景:
ClassPathXmlApplicationContext
:从类路径下的 XML 配置文件中加载上下文。FileSystemXmlApplicationContext
:从文件系统中的 XML 配置文件中加载上下文。AnnotationConfigApplicationContext
:基于注解的配置上下文,通常用于基于 Java 配置的应用程序。WebApplicationContext
:用于 Web 应用的上下文,实现了ApplicationContext
,并集成了 Servlet 环境。
3. 国际化支持
ApplicationContext
提供了对国际化(I18N)的支持,允许开发者根据用户的区域设置信息提供不同语言的消息。Spring 通过 MessageSource
接口实现了对国际化消息的管理,可以在配置文件中或通过 Java 类来定义国际化消息。
国际化消息文件
国际化消息通常存储在 .properties
文件中,不同语言的消息文件名称会有所区别,例如:
messages.properties
:默认语言messages_en.properties
:英文messages_fr.properties
:法语
使用 MessageSource
配置 MessageSource
来加载国际化消息:
XML 配置:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages" />
</bean>
Java 配置:
@Configuration
public class AppConfig {
@Bean
public ResourceBundleMessageSource messageSource() {
ResourceBundleMessageSource source = new ResourceBundleMessageSource();
source.setBasename("messages");
return source;
}
}
使用国际化消息:
@Autowired
private MessageSource messageSource;
public void printMessage(Locale locale) {
String message = messageSource.getMessage("greeting", null, locale);
System.out.println(message);
}
通过 Locale
参数,开发者可以获取基于不同语言环境的消息。
4. 事件处理机制
Spring 的事件机制使得应用程序中的组件之间可以通过发布和监听事件进行松散耦合的通信。Spring 提供了简单且强大的事件处理机制,基于 Observer Design Pattern(观察者模式)。
核心接口与类:
ApplicationEvent
:所有事件类的父类,开发者可以自定义事件,继承自该类。ApplicationListener
:事件监听器接口,开发者可以实现该接口来处理事件。ApplicationEventPublisher
:事件发布接口,Spring IoC 容器实现了该接口,开发者可以通过它发布事件。
自定义事件:
public class CustomEvent extends ApplicationEvent {
public CustomEvent(Object source) {
super(source);
}
}
自定义监听器:
@Component
public class CustomEventListener implements ApplicationListener<CustomEvent> {
@Override
public void onApplicationEvent(CustomEvent event) {
System.out.println("Received custom event: " + event.getSource());
}
}
发布事件:
@Component
public class EventPublisher {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void publishEvent() {
CustomEvent customEvent = new CustomEvent(this);
applicationEventPublisher.publishEvent(customEvent);
}
}
在这个机制中,监听器通过实现 ApplicationListener
接口来处理特定的事件,发布器通过 ApplicationEventPublisher
接口发布事件,Spring IoC 容器负责监听器和事件的管理。
5. 资源访问
Spring Context 模块提供了统一的资源访问接口 Resource
,可以用来访问各种形式的资源文件,如文件、URL、classpath 等。
获取资源:
Resource resource = applicationContext.getResource("classpath:data.txt");
InputStream inputStream = resource.getInputStream();
不同的资源前缀表示不同的资源类型:
classpath:
:类路径下的资源file:
:文件系统中的资源http:
:通过 HTTP 访问的资源
在这里插入图片描述
6. 生命周期管理
Spring 提供了对 Bean 生命周期的全面管理,ApplicationContext
扩展了 BeanFactory
的功能,并提供了更加细粒度的生命周期控制。Bean 的生命周期包括初始化、依赖注入、初始化回调、销毁等阶段。
生命周期回调:
InitializingBean
和DisposableBean
接口:这些接口允许在 Bean 初始化和销毁时执行自定义逻辑。@PostConstruct
和@PreDestroy
注解:用于定义 Bean 初始化和销毁的回调方法。init-method
和destroy-method
:在 XML 或 Java 配置中定义 Bean 的初始化和销毁方法。
生命周期回调示例:
@Component
public class MyBean implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() {
System.out.println("Bean 初始化");
}
@Override
public void destroy() {
System.out.println("Bean 销毁");
}
}
7. Environment 抽象
Spring Environment
抽象用于管理与应用程序运行环境相关的配置。它提供了配置文件、系统属性和环境变量等信息的统一访问方式。Environment
接口还支持对配置文件的处理,例如 dev
、test
、prod
环境的动态切换。
访问环境属性:
@Component
public class MyBean {
@Autowired
private Environment env;
public void printProperty() {
String dbUrl = env.getProperty("database.url");
System.out.println("Database URL: " + dbUrl);
}
}
8. ApplicationContext 的扩展
Spring 提供了 ApplicationContext
的扩展,使其能够支持多种功能,如 Web 应用中的 WebApplicationContext
,它是一个专用于 Web 环境的 ApplicationContext
,与 Servlet 环境集成紧密,能够管理 Web 应用的生命周期、请求作用域 Bean、会话作用域 Bean 等。
WebApplicationContext 示例:
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfig.class);
servletContext.addListener(new ContextLoaderListener(context));
}
}
总结
Spring Context 模块扩展了基础的 Bean 管理功能,提供了更为全面的应用上下文管理。通过 ApplicationContext
,开发者可以实现国际化、事件传播、资源访问、环境配置、生命周期管理等高级功能。这些特性为企业级应用程序开发提供了强大的支持,使应用程序更加灵活、可扩展和易于维护。
Spring Context 是 Spring 框架的中枢模块之一,它整合了大量企业级功能,并且可以通过注解、XML 和 Java 配置灵活定义和管理上下文,满足不同类型应用的需求。