1.IOC定义
IOC(Inversion of control)控制反转。在没有IOC的传统开发模式中,对象的创建和对象之间的依赖关系由程序代码直接控制,这导致了高耦合和低灵活性。
IOC实际上是一种设计原则,可以通过依赖注入(Dependency Injection,DI)的方式来实现,DI是IOC的一种实现方式。通过IOC容器,对象的创建和生命周期管理由Spring框架接管,而不是由对象本身控制。
2.代码示例
2.1不使用Spring IOC的传统Java
// 接口
public interface HomeService {
String method();
}
// 实现接口
public class HomeServiceImpl implements HomeService {
@Override
public String method() {
return "坐动车";
}
}
//消费者
public class HomeConsumer {
HomeServiceImpl homeServiceImpl = new HomeServiceImpl();
public String goHomeMethod(){
String method = homeServiceImpl.method();
return method;
}
}
// 应用程序
public class Application {
public static void main(String[] args) {
//创建消费者对象
HomeConsumer home = new HomeConsumer();
//调消费者的方法
home.goHomeMethod();
System.out.println(home.goHomeMethod());
}
}
上面代码中,HomeConsumer
类直接创建了一个 homeServiceImpl
的实例,并在 goHomeMethod 方法中调用它来获取消息。这种方式有以下几个问题:
-
高耦合:Home
Consumer
类依赖于具体的 homeServiceImpl
类,如果需要更改为另一种出行服务,则必须修改 HomeConsumer
类的源代码。 -
低灵活性:由于 Home
Consumer
类直接控制了 homeServiceImpl
的创建,因此很难替换或者修改出行服务的实现,这限制了应用程序的灵活性。 -
难以测试:在单元测试 Home
Consumer
类时,很难对 homeServiceImpl
进行模拟,因为它是在 HomeConsumer
类内部创建的。
2.2使用Spring IOC的Java
// 服务接口和实现保持不变
// 消费者类
public class HomeConsumer {
//依赖注入,不在直接创建依赖
private HomeService homeService;
//构造方法依赖注入
public HomeConsumer(HomeService homeService) {
this.homeService = homeService;
}
public String goHomeMethod(){
String method = homeService.method();
return method;
}
public static void main(String[] args) {
// 使用Spring容器来获取HomeConsumer对象
ApplicationContext context = new AnotationConfigApplicationContext(HomeConsumer.class);
HomeConsumer consumer = context.getBean(HomeConsumer.class);
//调用消费者方法
consumer.goHomeMethod();
}
}
常见问题:
1.在一个类上面添加@Configuration注解
在一个类上添加 @Configuration
注解表明该类是一个配置类,这个配置类可包含定义和初始化Spring容器中bean的方法。这个注解是Spring基于Java的配置方式的核心部分,允许开发者用Java代码替代传统的XML文件来配置Spring容器。所以说,@Configuration
注解的类是Spring中的配置中心,它提供了一种声明式的方法来定义和管理bean,使得Spring的配置更加灵活和强大。
2.用@Configuration标明的配置类可包含定义和初始化Spring容器中bean的方法
/**
* AppConfig 类使用 @Configuration 注解,表明它是一个Spring配置类。
* 其中定义了两个bean:MessageService 和MessageConsumer。
*/
@Configuration
public class AppConfig {
/**
* messageService() 方法使用 @Bean 注解,表明它返回的对象应该被注册为一个bean。
* 在这个例子中,它返回了 MessageServiceImpl 的一个新实例。
* Spring容器会调用这个方法,并将返回的对象存储在容器中,以便可以在其他地方注入或使用。
*/
@Bean
public MessageService messageService() {
return new MessageServiceImpl();
}
/**
* messageConsumer() 方法也使用 @Bean 注解,并且它接受一个 MessageService 参数。
* Spring容器会自动注入之前创建的 MessageService bean。
* 这个方法创建了一个 MessageConsumerImpl 的实例
* 该实例依赖于 MessageService。这展示了如何在一个bean的定义中注入另一个bean。
*/
@Bean
public MessageConsumer messageConsumer(MessageService messageService) {
return new MessageConsumerImpl(messageService);
}
}
//声明一个接口
interface MessageService {
String getMessage();
}
//声明一个实现类
class MessageServiceImpl implements MessageService {
public String getMessage() {
return "Hello, World!";
}
}
/**
* MessageConsumer 是一个类,它依赖于 MessageService
* 它有一个 processMessages() 方法,该方法调用 messageService.getMessage()
*/
class MessageConsumer {
private MessageService messageService;
public MessageConsumer(MessageService messageService) {
this.messageService = messageService;
}
public void processMessages() {
System.out.println(messageService.getMessage());
}
}
3.Spring应用程序中初始化Spring上下文的含义
启动Spring容器并加载配置信息,创建和管理应用程序中的bean。Spring上下文(应用上下文)是Spring中进行依赖注入和bean生命周期管理的核心容器。
4."获取 MessageConsumer bean"的含义
意味着从Spring容器中检索一个名为MessageConsumer的bean实例。在Spring容器中,bean是被管理的对象,它们可以通过配置(XML或注解)定义,Spring容器负责创建和组装这些bean。
5.初始化Spring上下文并获取MessageConsumer bean的过程
5.1 定义配置
如前面示例中所展示的,通过@Configuration
注解的类(如AppConfig
)定义了应用程序中的bean和服务。
5.2启动Spring容器
通过创建AnnotationConfigApplicationContext
实例来启动Spring容器,并将配置类(如AppConfig
)传递给它。这个动作会触发Spring容器根据配置类中的定义创建和初始化所有的bean。
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
5.3获取Bean
一旦Spring容器初始化完成,您可以通过调用getBean()方法来获取容器中的bean。在这个例子中,我们要获取的是MessageConsumer类型的bean。
MessageConsumer consumer = context.getBean(MessageConsumer.class);
5.4 使用bean
获取到MessageConsumer
实例后,您可以使用这个bean,如调用它的方法执行业务逻辑。
consumer.processMessages(); // 调用MessageConsumer中的方法
在整个过程中,Spring容器负责处理bean的创建、依赖注入、生命周期管理等。开发者只需要通过配置来指导Spring如何组装应用程序,剩下的工作(如创建对象、注入依赖)都由Spring自动完成。这就是所谓的"控制反转"(Inversion of Control,IoC),它是Spring框架的核心原理之一。