Spring 容器详解

Spring容器的本质

什么是Spring容器?

Spring容器本质上是一个对象工厂,它负责创建、配置和管理应用程序中的对象(称为Bean)。容器是Spring框架的核心,所有的Spring功能都基于容器实现。

注意:这里说的 【 创建、配置、管理 】应用程序中的对象,应该深刻理解。# 【附录】举例说明Spring是如何进行 创建、配置和管理 对象的呢?

容器的核心作用

  1. 对象创建: 负责创建应用程序中需要的所有对象
  2. 依赖管理: 自动注入对象之间的依赖关系
  3. 生命周期管理: 管理对象的创建、初始化、使用和销毁
  4. 配置管理: 统一管理对象的配置信息

Spring容器的构成

注意:这里说的 Spring容器 为 BeanFactory和ApplicationContext,需要思考,他们并没有用于储存bean的map或者list,为什么说他们是 spring的容器?【附录】为什么说BeanFactory和ApplicationContext是Spring容器?

1. BeanFactory - 基础容器

BeanFactory是Spring容器的基础接口,提供了最基本的IoC功能:

java 复制代码
public interface BeanFactory {
    // 根据名称获取Bean
    Object getBean(String name);
    
    // 根据类型获取Bean
    <T> T getBean(Class<T> requiredType);
    
    // 根据名称和类型获取Bean
    <T> T getBean(String name, Class<T> requiredType);
    
    // 检查Bean是否存在
    boolean containsBean(String name);
    
    // 检查Bean是否为单例
    boolean isSingleton(String name);
    
    // 获取Bean的类型
    Class<?> getType(String name);
}

BeanFactory的特点:

  • 延迟加载:只有在请求Bean时才创建
  • 功能简单:只提供基本的IoC功能
  • 轻量级:占用资源少

2. ApplicationContext - 高级容器

ApplicationContextBeanFactory的子接口,提供了更多企业级功能:

java 复制代码
public interface ApplicationContext extends BeanFactory {
    // 获取应用名称
    String getApplicationName();
    
    // 获取启动时间
    long getStartupDate();
    
    // 获取父容器
    ApplicationContext getParent();
    
    // 获取环境信息
    Environment getEnvironment();
    
    // 发布事件
    void publishEvent(ApplicationEvent event);
    
    // 获取资源
    Resource getResource(String location);
}

ApplicationContext的特点:

  • 预加载:启动时就创建所有单例Bean
  • 功能丰富:支持AOP、事件、国际化等
  • 企业级:适合生产环境使用

3. 容器的核心组件

这里主要是归纳了,Spring容器中收纳的bean,以及对Bean进行更改的通用方法

BeanDefinition - Bean定义

spring环境中 的BeanDefinition 来源是由哪些?如何理解 BeanDefinition ,他在spring中起到了什么作用?解释点这里

java 复制代码
public interface BeanDefinition {
    // Bean的类名
    void setBeanClassName(String beanClassName);
    String getBeanClassName();
    
    // Bean的作用域
    void setScope(String scope);
    String getScope();
    
    // 是否懒加载
    void setLazyInit(boolean lazyInit);
    boolean isLazyInit();
    
    // 依赖的Bean
    void setDependsOn(String... dependsOn);
    String[] getDependsOn();
    
    // 初始化方法
    void setInitMethodName(String initMethodName);
    String getInitMethodName();
    
    // 销毁方法
    void setDestroyMethodName(String destroyMethodName);
    String getDestroyMethodName();
}

BeanPostProcessor - Bean后处理器

BeanPostProcessor有不同的实现,不同的实现在功能上会有所不同,即在增强或改变bean的时间节点会有所不同,增强或改变的逻辑也有所不同。解释点这里

java 复制代码
public interface BeanPostProcessor {
    // Bean初始化前的处理
    Object postProcessBeforeInitialization(Object bean, String beanName);
    
    // Bean初始化后的处理
    Object postProcessAfterInitialization(Object bean, String beanName);
}

BeanFactoryPostProcessor - 工厂后处理器

BeanFactoryPostProcessor与上面的BeanPostProcessor 所增强的对象会有所不同。解释点这里

java 复制代码
public interface BeanFactoryPostProcessor {
    // 在BeanFactory初始化后,Bean实例化前调用
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory);
}

Spring容器的实现类

这里只针对容器这一块来说明,是BeanFactory和ApplicationContext 的不同实现类,主要用在不同的场景下。

1. ClassPathXmlApplicationContext

java 复制代码
// 基于XML配置的容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = context.getBean(UserService.class);

2. AnnotationConfigApplicationContext

java 复制代码
// 基于注解配置的容器
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = context.getBean(UserService.class);

3. FileSystemXmlApplicationContext

java 复制代码
// 基于文件系统XML配置的容器
ApplicationContext context = new FileSystemXmlApplicationContext("C:/config/applicationContext.xml");

4. WebApplicationContext

java 复制代码
// Web应用专用的容器
// 在Spring MVC中使用

Spring容器的启动过程

注意:这里所有的容器启动,其实都是基于main方法的。不同的容器实现类,读取bean的方式不同,但最终都要进行context.refresh();即刷新容器,刷新容器有12大步骤。解释点这里

1. 容器初始化阶段

java 复制代码
// 1. 创建容器实例
ApplicationContext context = new AnnotationConfigApplicationContext();

// 2. 注册配置类
context.register(AppConfig.class);

// 3. 刷新容器
context.refresh();

2. Bean定义加载阶段

注意:bean加载阶段比较复杂,需要新的篇章来解释。解释点这里

java 复制代码
// 1. 扫描配置类
// 2. 解析@Bean注解
// 3. 扫描@Component等注解
// 4. 创建BeanDefinition

3. Bean实例化阶段

注意:bean的实例化阶段比较复杂,需要新的篇章来解释。解释点这里

java 复制代码
// 1. 创建Bean实例
// 2. 注入依赖
// 3. 调用初始化方法
// 4. 注册到容器

Spring容器的诞生是为了解决什么问题

1. 解决传统Java开发的问题

传统方式的问题:

java 复制代码
// 硬编码依赖,耦合度高
public class UserService {
    private UserDao userDao = new UserDaoImpl();
    private EmailService emailService = new EmailServiceImpl();
    
    public void registerUser(User user) {
        userDao.save(user);
        emailService.sendWelcomeEmail(user);
    }
}

Spring容器解决的问题:

java 复制代码
// 依赖由容器管理,松耦合
@Service
public class UserService {
    @Autowired
    private UserDao userDao;
    
    @Autowired
    private EmailService emailService;
    
    public void registerUser(User user) {
        userDao.save(user);
        emailService.sendWelcomeEmail(user);
    }
}

2. 实现控制反转(IoC)

传统方式:

  • 对象自己创建依赖
  • 对象自己管理生命周期
  • 对象之间耦合度高

Spring容器方式:

  • 容器负责创建对象
  • 容器负责注入依赖
  • 容器管理对象生命周期
  • 对象之间松耦合

3. 提供统一的配置管理

传统方式:

java 复制代码
// 配置分散在各个类中
public class UserDaoImpl implements UserDao {
    private String url = "jdbc:mysql://localhost:3306/test";
    private String username = "root";
    private String password = "123456";
}

Spring容器方式:

java 复制代码
// 统一配置管理
@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        return new DriverManagerDataSource(
            "jdbc:mysql://localhost:3306/test",
            "root",
            "123456"
        );
    }
}

4. 支持面向切面编程(AOP)

java 复制代码
// 通过容器实现AOP
@Component
public class LoggingAspect {
    @Around("@annotation(Loggable)")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("方法开始执行: " + joinPoint.getSignature());
        Object result = joinPoint.proceed();
        System.out.println("方法执行完成: " + joinPoint.getSignature());
        return result;
    }
}

容器的设计模式

1. 工厂模式

java 复制代码
// 容器作为对象工厂
public class BeanFactory {
    public Object getBean(String name) {
        // 创建和管理Bean
    }
}

2. 单例模式

java 复制代码
// 容器管理单例Bean
public class SingletonBeanRegistry {
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
    
    public Object getSingleton(String beanName) {
        return singletonObjects.get(beanName);
    }
}

3. 观察者模式

java 复制代码
// 容器支持事件机制
public class ApplicationEventMulticaster {
    public void multicastEvent(ApplicationEvent event) {
        // 发布事件给所有监听器
    }
}

容器的优势

1. 松耦合

  • 对象之间不直接依赖
  • 通过接口进行交互
  • 易于测试和维护

2. 可扩展性

  • 易于添加新功能
  • 支持插件式架构
  • 支持热插拔

3. 可测试性

  • 易于进行单元测试
  • 支持Mock对象
  • 支持测试隔离

4. 可维护性

  • 统一的配置管理
  • 清晰的依赖关系
  • 易于问题排查

总结

Spring容器是Spring框架的核心,它的本质是一个对象工厂,负责创建、配置和管理应用程序中的对象。

容器的构成:

  • BeanFactory:基础容器,提供基本IoC功能
  • ApplicationContext:高级容器,提供企业级功能
  • BeanDefinition:Bean的定义信息
  • BeanPostProcessor:Bean的后处理机制

容器的出发点:

  1. 解决传统Java开发的耦合问题
  2. 实现控制反转(IoC)
  3. 提供统一的配置管理
  4. 支持面向切面编程(AOP)

容器的优势:

  • 松耦合
  • 可扩展性
  • 可测试性
  • 可维护性

Spring容器通过统一的对象管理机制,大大简化了Java企业级应用的开发,提高了代码的质量和可维护性。

相关推荐
Victor35616 小时前
Hibernate(42)在Hibernate中如何实现分页?
后端
Victor35616 小时前
Hibernate(41)Hibernate的延迟加载和急加载的区别是什么?
后端
猪猪拆迁队16 小时前
2025年终总结-都在喊前端已死,这一年我的焦虑、挣扎与重组:AI 时代如何摆正自己的位置
前端·后端·ai编程
程序员小白条16 小时前
面试 Java 基础八股文十问十答第八期
java·开发语言·数据库·spring·面试·职场和发展·毕设
ConardLi16 小时前
SFT、RAG 调优效率翻倍!垂直领域大模型评估实战指南
前端·javascript·后端
Hooray17 小时前
2026年,站在职业生涯十字路口的我该何去何从?
前端·后端
唐叔在学习17 小时前
还在申请云服务器来传输数据嘛?试试P2P直连吧
后端·python
开心猴爷17 小时前
iOS 代码混淆在项目中的方式, IPA 级保护实践记录
后端
魅影骑士001018 小时前
柯里化函数
后端·设计模式
JOEH6018 小时前
🛡️ 微服务雪崩救星:Sentinel 限流熔断实战,3行代码搞定高可用!
后端·全栈