spring IOC AOP核心思想

spring IOC AOP核心思想_第1张图片

我的理解:一开始各个对象之间相互合作,是多个对象对应多个对象去使用,如果有一个对象出现问题就可能影响到全局,但是使用ioc就是在两者之间加入了一个中间媒介(spring bean也就是通过xml配置文件装配对象),如果相互需要,调用中间媒介即可,做到了极大的解耦。带来的问题是配置多运行效率就会降低。

什么是IOC?_贾州的博客-CSDN博客

控制反转名字的由来:

对象A获得依赖对象B的过程,由主动行为变为了被动行为,控制权颠倒过来了,这就是“控制反转”这个名称的由来。

spring IOC AOP核心思想_第2张图片

依赖注入:

public class OrderService {
    private PaymentService paymentService;
    
    // 通过构造函数注入依赖
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }
    
    public void processOrder(double amount) {
        // 使用注入的 PaymentService 对象进行支付处理
        paymentService.pay(amount);
        // 其他订单处理逻辑...
    }
}

public interface PaymentService {
    void pay(double amount);
}

public class PayPalPaymentService implements PaymentService {
    public void pay(double amount) {
        // 使用 PayPal 的支付逻辑进行支付
        // ...
    }
}

OrderService 类依赖于 PaymentService 接口来处理支付逻辑。OrderService通过自身构造函数注入PaymentService ,OrderService 不需要直接依赖于具体的支付服务实现类,而是通过接口进行依赖,并且在运行时由外部容器负责创建和注入具体的 PaymentService 实例。这就是在应用了依赖注入后,控制反转的过程。OrderService 将自身对于 PaymentService 的控制权转移到了外部容器,外部容器负责创建和注入所需的具体实现类的实例。具体的实现由PaymentService 的实现类去实现具体功能。

AOP核心思想理解:目标方法在执行前后做一些日志或者安全检测

假设我们有一个简单的账户管理系统,其中包含一个AccountService接口和其实现类AccountServiceImpl,并且我们希望在每个方法执行前后记录日志。

首先,我们需要引入一个AOP框架,比如AspectJ或Spring AOP。这里我使用Spring AOP来实现AOP的示例。

// 定义AccountService接口

public interface AccountService {

  void createAccount(String username);

  void deleteAccount(String username);

}

// AccountService接口的实现类

public class AccountServiceImpl implements AccountService {

  @Override

  public void createAccount(String username) {

    // 创建账户的具体逻辑

    System.out.println("创建账户:" + username);

  }

  @Override

  public void deleteAccount(String username) {

    // 删除账户的具体逻辑

    System.out.println("删除账户:" + username);

  }

}

接下来,我们创建一个切面类LoggingAspect来定义日志记录的横切逻辑。

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.springframework.stereotype.Component;

@Aspect

@Component

public class LoggingAspect {

  @Before("execution(* com.example.AccountService.*(..))")

  public void beforeMethodExecution(JoinPoint joinPoint) {

    String methodName = joinPoint.getSignature().getName();

    System.out.println("Before executing method: " + methodName);

  }

  @After("execution(* com.example.AccountService.*(..))")

  public void afterMethodExecution(JoinPoint joinPoint) {

    String methodName = joinPoint.getSignature().getName();

    System.out.println("After executing method: " + methodName);

  }

}

在上述代码中,我们使用了@Aspect注解和切点表达式来定义切面,@Before注解表示在目标方法执行前执行横切逻辑,@After注解表示在目标方法执行后执行横切逻辑。

最后,我们需要在Spring配置文件中配置AOP和Bean。



  <!-- 开启Spring的注解支持 -->

  <context:annotation-config />

  <!-- 启用AOP -->

  <aop:aspectj-autoproxy />

  <!-- 扫描切面类 -->

  <context:component-scan base-package="com.example" />

  <!-- 配置AccountService的Bean -->

  <bean id="accountService" class="com.example.AccountServiceImpl" />

</beans>

现在,当我们调用AccountService接口的方法时,AOP会自动在方法执行前后记录日志。例如:

public class Main {

  public static void main(String[] args) {

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    AccountService accountService = context.getBean(AccountService.class);

    accountService.createAccount("John"); // 输出:Before executing method: createAccount

      //       创建账户:John

      //       After executing method: createAccount

    accountService.deleteAccount("John"); // 输出:Before executing method: deleteAccount

      //       删除账户:John

      //       After executing method: deleteAccount

  }

}

通过使用AOP,我们可以在不修改业务逻辑的情况下,将共享的横切关注点(日志记录)与核心业务逻辑(创建和删除账户)分离开来,提高代码的可维护性和可重用性。

AOP应用场景:

AOP(Aspect-Oriented Programming)是一种编程范式,通过将横切关注点(cross-cutting concerns)与核心业务逻辑分离,以模块化的方式实现共享和重用。在AOP中,横切关注点指的是在一个应用程序中散布于各个模块的功能,如日志记录、安全性、事务管理等。

下面是几个常见的AOP的应用场景的例子:

  1. 日志记录:通过AOP可以很方便地在关键方法执行前后记录日志,而不需要在每个方法中编写重复的日志记录代码。例如,可以使用AOP在每个方法执行前打印方法名、参数和执行时间。
  2. 安全性:通过AOP可以实现对方法或资源的访问控制。例如,可以使用AOP实现基于角色的访问控制,在方法执行前检查当前用户是否具有足够的权限来执行该方法。
  3. 事务管理:通过AOP可以实现声明性事务管理,将事务管理逻辑从业务逻辑中分离出来。例如,可以使用AOP在方法执行前开启事务,在方法执行后根据执行结果提交或回滚事务。
  4. 缓存管理:通过AOP可以实现自动缓存功能,将缓存逻辑从业务逻辑中解耦。例如,可以使用AOP在方法执行前检查是否存在缓存结果,如果存在则直接返回缓存值,否则执行方法并将结果添加到缓存中。
  5. 异常处理:通过AOP可以统一处理方法抛出的异常,在一处地方捕获和处理异常,而不需要在每个方法中编写繁琐的异常处理代码。例如,可以使用AOP在方法执行时捕获异常并进行统一的日志记录或错误处理。

依赖注入三种方式:

构造函数注入:

public class UserService {
    private UserRepository userRepository;
    
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    // 使用userRepository进行相关操作的方法
}

set注入:向外部提供的是set方法

public class UserService {
    private UserRepository userRepository;
    
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    // 使用userRepository进行相关操作的方法
}

接口注入:接口注入其实实现类也是用的set方法,向外部提供的是一个接口

public interface UserRepositoryAware {
    void setUserRepository(UserRepository userRepository);
}

public class UserService implements UserRepositoryAware {
    private UserRepository userRepository;
    
    @Override
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    
    // 使用userRepository进行相关操作的方法
}

你可能感兴趣的:(spring,spring,java,mysql)