Spring依赖注入、控制反转、面向切面编程三大特性详解(含示例代码)

目录

 

总结

AOP(Aspect-Oriented Programming,面向切面)

Spring IOC(Inversion of Control,控制反转)

依赖注入(Dependency Injection,DI)

构造函数注入

Setter 方法注入

接口注入


 

总结

Spring 框架是一个开源的企业级应用程序开发框架,它提供了许多功能和特性,但主要包括以下三大核心特性:

  1. 依赖注入(Dependency Injection,DI): 依赖注入是 Spring 的核心特性之一。它通过控制反转(Inversion of Control,IOC)实现对象之间的解耦。在传统的编程模型中,对象自己负责创建和管理它所依赖的对象,而在 Spring 中,容器负责创建对象,并将依赖关系注入到对象中。这样可以提高代码的可维护性、可测试性和松耦合性。

  2. 面向切面编程(Aspect-Oriented Programming,AOP): AOP 是 Spring 的另一个重要特性,它通过将横切关注点(cross-cutting concerns)从核心业务逻辑中分离出来,实现了对横切关注点的模块化和复用。横切关注点是指在一个应用程序中多处重复出现的功能或行为,例如日志记录、事务管理、安全性等。在 Spring AOP 中,通过定义切面(Aspect)和通知(Advice),可以将横切关注点与业务逻辑解耦,从而提高代码的可维护性和可重用性。

  3. 面向接口编程(Interface-Based Programming): Spring 鼓励使用接口来定义组件之间的契约,这种编程方式被称为面向接口编程。通过面向接口编程,可以实现组件之间的解耦,并提供灵活的扩展和替换能力。Spring 提供了对接口的依赖注入支持,可以根据接口定义的契约自动装配具体实现。这样,我们可以根据需要更换不同的实现,而不需要修改依赖的组件。

这些特性使得 Spring 框架成为一个功能强大且灵活的框架,可以简化企业级应用程序的开发和维护工作。下面详细说一下每一个特性并附上代码。

AOP(Aspect-Oriented Programming,面向切面)

AOP是一种编程范式,提供一种将横切关注点(cross-cutting concerns)从核心业务逻辑中分离出来的方式。横切关注点是指在一个应用程序中多处重复出现的功能或行为,例如日志记录、事务管理、安全性等。AOP 的目标是通过在应用程序中定义切面(aspects),将这些横切关注点模块化,从而提高代码的可维护性、可重用性和可测试性。

AOP 的核心思想是通过将横切关注点与核心业务逻辑分离,将其作为独立的模块来处理。在 AOP 中,切面定义了在应用程序中多个位置执行的横切关注点。切面可以通过使用不同的通知(advice)类型来描述在何时执行横切关注点,例如在方法执行前、执行后或异常抛出时等。通知是切面的具体实现,可以包含需要执行的代码。

示例代码演示了如何使用 AOP 在 Java 中实现日志记录的横切关注点:

// 日志切面类
public aspect LoggingAspect {
  
  // 在方法执行前执行通知
  before(): execution(* com.example.myapp.*.*(..)) {
    System.out.println("Entering method: " + thisJoinPoint.getSignature().getName());
  }
  
  // 在方法执行后执行通知
  after(): execution(* com.example.myapp.*.*(..)) {
    System.out.println("Exiting method: " + thisJoinPoint.getSignature().getName());
  }
  
  // 在方法抛出异常时执行通知
  after() throwing(Throwable e): execution(* com.example.myapp.*.*(..)) {
    System.out.println("Exception thrown: " + e);
  }
}

我们定义了一个切面类 LoggingAspect,其中包含了三个通知。before 通知在目标方法执行前打印日志,after 通知在目标方法执行后打印日志,after throwing 通知在目标方法抛出异常时打印日志。这些通知通过使用 execution 表达式指定了切入点,即要拦截的方法。

要在应用程序中使用 AOP,需要使用支持 AOP 的框架。常见的 Java AOP 框架包括 AspectJSpring AOP 等。这些框架提供了更强大的 AOP 功能和更灵活的配置选项。

Spring IOC(Inversion of Control,控制反转)

Spring IOC是 Spring 框架的核心概念之一。它是一种设计原则,通过将对象的创建和依赖关系的管理交给容器来实现。在传统的编程模型中,对象的创建和管理由开发者手动完成,而在 Spring IOC 中,这些任务由 Spring 容器自动完成。

IOC 的核心思想是通过依赖注入(Dependency Injection,DI)来实现对象之间的解耦。在 IOC 容器中,开发者只需要定义对象的声明,包括其依赖关系,而无需关心对象的创建和管理。容器会负责创建对象,并将依赖关系注入到对象中。

示例代码:

// 定义一个接口
public interface GreetingService {
    void sayHello();
}

// 实现接口
public class GreetingServiceImpl implements GreetingService {
    public void sayHello() {
        System.out.println("Hello, World!");
    }
}

// 在 Spring 配置文件中声明 Bean
<bean id="greetingService" class="com.example.GreetingServiceImpl"/>

// 使用 IOC 容器获取 Bean 并调用方法
public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        GreetingService greetingService = context.getBean("greetingService", GreetingService.class);
        greetingService.sayHello();
    }
}

首先定义了一个接口 GreetingService,然后实现了该接口的 GreetingServiceImpl 类。接下来,在 Spring 配置文件中声明了一个名为 "greetingService" 的 Bean,并指定其实现类为 GreetingServiceImpl

MainApp 类中,我们使用 ApplicationContext 接口创建了一个 Spring IOC 容器,并加载了配置文件 "spring-config.xml"。然后,通过调用 getBean() 方法从容器中获取名为 "greetingService" 的 Bean,并将其转型为 GreetingService 接口类型。最后,我们调用 sayHello() 方法输出 "Hello, World!"。

通过使用 Spring IOC,我们可以实现对象的解耦和灵活性。开发者只需要关注对象的声明和依赖关系,而无需关心对象的创建和管理,这样可以提高代码的可维护性和可测试性。

依赖注入(Dependency Injection,DI)

依赖注入(Dependency Injection,DI)是一种实现控制反转(Inversion of Control,IOC)的机制,用于解决对象之间的依赖关系。通过依赖注入,对象的依赖关系由容器负责管理和注入,而不是由对象自身创建和管理依赖。

依赖注入有三种主要的注入方式:构造函数注入Setter 方法注入和接口注入。下面将分别介绍这三种注入方式并提供相应的代码示例。

构造函数注入

通过对象的构造函数注入依赖。在创建对象时,容器会将所需的依赖作为参数传递给对象的构造函数。

public class GreetingServiceImpl implements GreetingService {
    private MessageService messageService;

    public GreetingServiceImpl(MessageService messageService) {
        this.messageService = messageService;
    }

    public void sayHello() {
        String message = messageService.getMessage();
        System.out.println("Hello, " + message);
    }
}

Setter 方法注入

通过对象的 Setter 方法注入依赖。容器会调用对象的 Setter 方法,将依赖作为参数传递给该方法。

public class GreetingServiceImpl implements GreetingService {
    private MessageService messageService;

    public void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }

    public void sayHello() {
        String message = messageService.getMessage();
        System.out.println("Hello, " + message);
    }
}

接口注入

通过对象实现的接口来注入依赖。对象会实现一个接口,在接口中定义一个用于注入依赖的方法。

public interface MessageServiceAware {
    void setMessageService(MessageService messageService);
}

public class GreetingServiceImpl implements GreetingService, MessageServiceAware {
    private MessageService messageService;

    public void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }

    public void sayHello() {
        String message = messageService.getMessage();
        System.out.println("Hello, " + message);
    }
}

代码示例中的 GreetingServiceImpl 类表示一个服务类,依赖于 MessageService 接口。在构造函数注入和 Setter 方法注入示例中,GreetingServiceImpl 类通过构造函数和 Setter 方法分别接收一个 MessageService 实例,并将其保存为依赖。在接口注入示例中,GreetingServiceImpl 类实现了 MessageServiceAware 接口,并提供了一个方法用于接收 MessageService 实例。

通过使用 Spring 的依赖注入,我们可以将依赖关系从对象自身解耦,提高代码的可测试性和可维护性。Spring 容器会负责创建对象,并自动注入所需的依赖。我们只需要在配置文件或注解中指定依赖关系,Spring 就会完成剩余的工作。另外,Spring 还提供了其他高级的依赖注入功能,例如自动装配(Autowiring)、注解驱动的依赖注入等。 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫飞雪飘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值