spring IOC AOP核心思想

news2024/11/16 15:28:35

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

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

控制反转名字的由来:

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

依赖注入:

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。

<beans xmlns="[http://www.springframework.org/schema/beans](http://www.springframework.org/schema/beans)"

  xmlns:context="[http://www.springframework.org/schema/context](http://www.springframework.org/schema/context)"

  xmlns:aop="[http://www.springframework.org/schema/aop](http://www.springframework.org/schema/aop)"

  xsi:schemaLocation="[http://www.springframework.org/schema/beans](http://www.springframework.org/schema/beans) 

    [http://www.springframework.org/schema/beans/spring-beans.xsd](http://www.springframework.org/schema/beans/spring-beans.xsd) 

    [http://www.springframework.org/schema/context](http://www.springframework.org/schema/context)

    [http://www.springframework.org/schema/context/spring-context.xsd](http://www.springframework.org/schema/context/spring-context.xsd)

    [http://www.springframework.org/schema/aop](http://www.springframework.org/schema/aop) 

    [http://www.springframework.org/schema/aop/spring-aop.xsd](http://www.springframework.org/schema/aop/spring-aop.xsd)">

  &lt;!-- 开启Spring的注解支持 --&gt;

  &lt;context:annotation-config /&gt;

  &lt;!-- 启用AOP --&gt;

  &lt;aop:aspectj-autoproxy /&gt;

  &lt;!-- 扫描切面类 --&gt;

  &lt;context:component-scan base-package="com.example" /&gt;

  &lt;!-- 配置AccountService的Bean --&gt;

  &lt;bean id="accountService" class="com.example.AccountServiceImpl" /&gt;

&lt;/beans&gt;

现在,当我们调用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进行相关操作的方法
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1078140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pytorch中nn.DataParallel多次使用

pytorch中nn.DataParallel多次使用 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader# 定义模型 class MyModel(nn.Module):def __init__(self):super(MyModel, self).__init__()self.fc nn.Linear(10, 1)def forwa…

Filebeat、metricbeat、kafka

kibana机子上安装filebrat&#xff08;因为有nginx&#xff09; 上传filebrat包 在es概览查看 上传metricbeat 排错 tailf !$ Kibana-Vlsualize查看 kafka(卡夫卡) kafka是一个分布式的消息发布—订阅系统&#xff08;kafka其实是消息队列&#xff09;消息队列中间件 Kafka的…

二十、SpringCloud Alibaba Seata处理分布式事务

目录 一、分布式事务问题1、分布式之前2、分布式之后 二、Seata简介1、Seata是什么&#xff1f;2、Seata能干嘛&#xff1f;3、去拿下&#xff1f;4、怎么玩 三、Seata-server安装四、订单、库存、账户业务数据库准备五、订单、库存、账户业务微服务准备六、Seata原理介绍 一、…

查杀Linux服务器病毒进程并对Linux中的文件描述符FD进行简单探索

一直以来&#xff0c;我都十分推崇把看到的理论知识与实际相结合。 在今天查杀服务器病毒程序的过程中&#xff0c;顺便挖掘了一些新的知识&#xff0c;现在把他总结成一篇文章记录一下。 每一个进程都有一个文件描述符表(通过lsof -p 进程号)&#xff0c;文件描述表是操作系统…

web基础以及http协议

web基础&#xff0c;http协议 域名&#xff1a;www.88886.co DNS解析 静态页面 动态页面 DNS域名&#xff1a; 网络上的通信都是基于IP通信模式&#xff1a;TCP/IP TCP建立连接和断开连接&#xff0c;都是要双方进行确认的 建立连接&#xff1a;三次握手 断开连接&#x…

.net mvc 无法创建虚拟目录和无法启动IIS Express Web服务器指定的url无效 解决方法

.net mvc 无法创建虚拟目录 修改项目配置中web中的项目url时&#xff0c;提示无法创建虚拟目录&#xff0c;则把ip地址改为localhost再进行创建即可 无法启动IIS Express Web服务器指定的url无效 解决方法 不要勾选【覆盖应用程序根URL&#xff08;U&#xff09;】,或让【覆盖…

js中进行数字,超大金额(千位符)格式化处理

前言 最近遇到一个需求,对于社区里讨论的帖子展示一个访问量的计数显示问题,当超过多少页面访问量时,就让其显示xxx万,xx亿 对于后台返回该字段的数据类型是number,需要进行格式化数字的输出 这个应用场景在前端开发中其实很普遍,例如:音乐app里面音乐歌曲播放数量,微博里的…

Unity中Shader的Lambert光照的实现

文章目录 前言一、分别获取Lambert光照模型的每个参数Lambert光照模型公式1、使用 Unity 封装的参数 unity_AmbientSky 获取环境光色2、在属性面板定义一个float类型参数作为光照系数3、获取主平行光的颜色4、获取世界空间下的顶点法向量5、获取反射点指向光源的向量6、使用Lam…

C++day04(类中特殊成员函数、匿名对象、友元、常成员函数和常对象、运算符重载)

1> 思维导图 2> 整理代码 代码&#xff1a; 算术运算符重载&#xff1a; #include <iostream>using namespace std; class Person {//全局函数实现运算符重载需要权限friend const Person operator(const Person L,const Person R); private:int a;int b; publi…

基于Springboot实现点餐平台网站管理系统项目【项目源码+论文说明】分享

基于Springboot实现点餐平台网站管理系统演示 摘要 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多商家的之中&#xff0c;随之就产生了“点餐平台网站”&#xff0c;这样就让点餐平台网站更加方便简单。 对于本…

泛函的含义,泛函分析

经常有同事和朋友讨论泛函分析是做什么的&#xff0c;所以做个小log 1. 泛函的含义 泛函的含义&#xff0c;笼统说&#xff0c;泛函是符合某种性质的任意函数&#xff1b;因为是任意的&#xff0c;所以就是泛泛的&#xff1b;但也没有不着边际的泛。 2. 泛函的例子 2.1 符合半…

uniapp+vue3+ts+uview-plus搭建项目步骤

创建项目 使用Vue3/Vite版&#xff0c;创建以 typescript 开发的工程 下载仓库 DCloud/uni-preset-vue - Gitee.com node版本&#xff1a;v16.18.0 npm版本&#xff1a; v8.19.2 依赖下载 解压之后&#xff0c;在vscode打开 通过终端运行 npm 命令下载依赖&#xff1a;npm ins…

1. Windows平台下如何编译C++版本的Redis库hiredis

Redis是一个key-value存储系统。和Memcached类似&#xff0c;它支持存储的value类型相对更多&#xff0c;包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash&#xff08;哈希类型&#xff09;。这些数据类型都支持push/pop、add/remove及取交集并…

Java中的抽象类和接口(Abstract Class and Interface)的区别

在Java面向对象编程中&#xff0c;总会用到接口和抽象类&#xff0c;他们都是对事物的一种抽象&#xff0c;有一些共同点但是也有很多区别。 接口Interface 在Java中接口需要用interface关键字定义&#xff0c;他是对一种行为的抽象&#xff0c;是一种约定的协议&#xff0c;…

微信小程序通过 movable-area 做一个与vuedraggable相似的上下拖动排序控件

因为只是做个小案例 我就直接代码写page页面里了 其实很简单 组件稍微改一下就好了 wxss /* 设置movable-area的宽度 */ .area{width: 100%; }/* a b c 每条元素的样式 */ movable-view {width: 100%;background-color: red;height: 40px;line-height: 40px;color: #FFFFFF;tex…

C语言进阶第五课-----------字符函数和字符串函数

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; ​&#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382; &#x1f389;&#x1f389;&#x1f389…

库存管理方法有哪些?

本文将为大家讲解&#xff1a;库存管理方法有哪些&#xff1f; 库存管理是企业运营中的核心环节&#xff0c;它涉及到货物的采购、存储、销售和配送。有效的库存管理可以确保企业有足够的货物满足客户的需求&#xff0c;同时避免库存积压和浪费。为了达到这个目标&#xff0c;…

免费开源的非标项目型制造BOM一键导入方案介绍

非标项目型制造&#xff0c;每一个订单都会引入很多新料号、新BoM、新工艺路线。实施ERP/MES系统&#xff0c;实现生产管理数字化&#xff0c;第一步就是要导入这些料号、BoM和工艺。项目型制造&#xff0c;大多数订单只生产一次。但在ERP/MES系统中&#xff0c;订单的料号、Bo…

软件测试之概念篇2(瀑布模型、螺旋模型、增量模型和迭代模型、敏捷模型,V模型、W模型)

目录 开发模型 &#xff08;1&#xff09;瀑布模型 &#xff08;2&#xff09;螺旋模型 &#xff08;3&#xff09;增量模型和迭代模型 &#xff08;4&#xff09;敏捷模型 &#xff08;5&#xff09;测试模型&#xff08;V模型、W模型&#xff09; V模型 W模型 开发模型…

计算机等级考试—信息安全三级真题十

目录 一、单选题 二、填空题 三、综合题 一、单选题