Spring容器的IOC

本文介绍了控制反转(IoC)的概念,特别是通过Spring框架的依赖注入实现。对比了传统Java开发中硬编码依赖和使用SpringIoC后的代码结构,强调了IoC在减少耦合性、提高灵活性和测试性方面的优势。
摘要由CSDN通过智能技术生成

        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 方法中调用它来获取消息。这种方式有以下几个问题:

  1. 高耦合:HomeConsumer 类依赖于具体的 homeServiceImpl 类,如果需要更改为另一种出行服务,则必须修改 HomeConsumer 类的源代码。

  2. 低灵活性:由于 HomeConsumer 类直接控制了 homeServiceImpl 的创建,因此很难替换或者修改出行服务的实现,这限制了应用程序的灵活性。

  3. 难以测试:在单元测试 HomeConsumer 类时,很难对 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框架的核心原理之一。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值