控制反转(IoC)和依赖注入(DI)是Spring框架中的两个基本概念。传统上,对象负责创建和管理它们自己的依赖关系。然而,IoC 通过将对象创建和依赖管理的控制权移交给像 Spring 这样的框架来翻转这一责任。
这种转变有几个优点:
IoC 可以通过各种机制来实现,包括工厂模式、策略模式或服务定位器模式等设计模式。然而,实现 IoC 最常见、最强大的方法是通过依赖注入。
依赖注入(DI)是一种框架将依赖项注入对象而不是对象本身创建依赖项的技术。 Spring中有不同类型的DI:
例如,在一个简单的服务类中,您可能会看到这样的内容:
@Service public class OrderService { private final PaymentService paymentService; @Autowired public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void processOrder(Order order) { paymentService.processPayment(order.getPaymentDetails()); } }
这里,PaymentService通过构造函数注入的方式注入到OrderService中,这种方式通常因其依赖关系清晰且易于测试而受到青睐。
Spring提供了一个IoC容器,负责管理bean(Spring管理的对象)的生命周期。这个容器的基本接口是BeanFactory。然而,大多数应用程序使用 ApplicationContext,它扩展了 BeanFactory 并提供了附加功能。
// Getting a bean from the ApplicationContext ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); MyBean myBean = context.getBean(MyBean.class);
在此示例中,ApplicationContext 用于检索 bean。如果您使用基本的 BeanFactory,它将提供类似的功能,但没有 ApplicationContext 的额外好处。
访问当前ApplicationContext有两种常用的方式:
Autowired:将 ApplicationContext 直接注入到您的组件中。
@Autowired private ApplicationContext applicationContext;
ApplicationContextAware:实现ApplicationContextAware接口,它允许您根据需要检索ApplicationContext。
public class MyBean implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext context) throws BeansException { this.applicationContext = context; } }
当 Spring 应用程序启动时,会发生一系列步骤:
处理环境变量和属性:创建环境对象,合并 application.properties 或 application.yml 中的设置。
创建ApplicationContext:确定并实例化适当的ApplicationContext类型。例如,Spring Boot 应用程序可以使用 AnnotationConfigServletWebServerApplicationContext 进行基于 Java 的配置。
加载Bean定义:Spring从多个源加载bean定义,例如带注释的类、@Configuration类或XML文件。每个 bean 定义都包含有关 bean 的类型、范围、依赖项和生命周期回调的信息。
处理 BeanFactoryPostProcessors:这些处理器在创建实际 bean 之前修改 bean 定义。
依赖关系解析和 Bean 创建:ApplicationContext 解析依赖关系并创建 Bean。如果一个 bean 依赖于其他 bean,则首先创建这些依赖关系。
Spring支持各种bean作用域,它们定义容器内bean的生命周期和可见性:
@Bean @Scope("prototype") public MyPrototypeBean myPrototypeBean() { return new MyPrototypeBean(); }
在此示例中,每次从容器请求时都会创建一个新的 MyPrototypeBean 实例。
考虑一个场景,其中 Singleton 范围的 bean 依赖于 Prototype 范围的 bean。通常,原型 bean 仅在单例初始化期间创建一次。为了确保每次都提供原型 bean 的新实例,Spring 使用代理对象。
@Component @Scope(value = "singleton") public class SingletonBean { @Autowired @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) private PrototypeBean prototypeBean; public void showMessage() { System.out.println(prototypeBean.getMessage()); } }
这里,ScopedProxyMode.TARGET_CLASS 确保每次调用 getMessage() 时都会返回一个新的 PrototypeBean 实例。
Spring Boot 是 Spring 框架的扩展,可简化新 Spring 应用程序的设置和开发。它提供:
自动配置是 Spring Boot 中的一项强大功能,它可以根据类路径中的依赖项为您配置许多内容。这是由条件注释控制的,例如:
例如,如果您的类路径中有 Jackson,Spring Boot 将自动配置一个用于 JSON 序列化的 ObjectMapper:
@Configuration @ConditionalOnClass(ObjectMapper.class) public class JacksonAutoConfiguration { // Configuration details... }
如果存在 ObjectMapper,则会自动应用此配置。否则,将被跳过。
您可以通过将以下内容添加到 application.properties 来在启动期间记录活动的自动配置:
logging.level.org.springframework.boot.autoconfigure=DEBUG
这将生成一份详细报告,显示哪些配置已应用,哪些配置未应用,帮助您排除故障或了解应用程序的配置。
控制反转和依赖注入是核心概念,它们实现了灵活性、模块化和可测试性,使 Spring 变得如此强大。通过了解 Spring 的 IoC 容器如何工作、如何管理 bean 以及 Spring Boot 如何扩展这些功能,您可以更有效地开发健壮、可维护的应用程序。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3