IoC和AOP

技术为解决某个问题而诞生

Spring 支持的控制反转(Inversion of Control,缩写为IoC)和面向切面编程(Aspect-oriented programming,缩写为AOP).主要用到的设计模式有工厂模式和代理模式。IOC就是典型的工厂模式,通过sessionfactory去注入实例。AOP就是典型的代理模式的体现。
spring的IoC容器是spring的核心,spring AOP是spring框架的重要组成部分。



没有IoC时传统三层架构

三层架构是经典的开发模式,我们一般将视图控制、业务逻辑和数据库操作分别抽离出来单独形成一个类,这样各个职责就非常清晰且易于复用和维护。 业界普遍按这种分层方式组织代码,其核心思想是职责分离层次越低复用程度越高,比如一个 DAO 对象往往会被多个 Service 对象使用,一个 Service 对象往往也会被多个 Controller 对象使用。

//Servlet进行开发

@WebServlet("/user")
public class UserServlet extends HttpServlet {
    // 用于执行业务逻辑的对象
    private UserService userService = new UserServiceImpl();
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // ...省略其他代码
            
        // 执行业务逻辑
        userService.doService();
        
        // ...返回页面视图
    }
}

public class UserServiceImpl implements UserService{
    // 用于操作数据库的对象
    private UserDao userDao = new UserDaoImpl();
    
    @Override
    public void doService() {
        // ...省略业务逻辑代码
            
        // 执行数据库操作
        userDao.doUpdate();
        
        // ...省略业务逻辑代码
    }
}

public class UserDaoImpl implements UserDao{
    @Override
    public void doUpdate() {
        // ...省略JDBC代码
    }
}

在这里插入图片描述

不足在于:

  1. 三层架构做到了逻辑复用,并没有做到资源复用。 上层调用下一层时,必然会持有下一层的对象引用,即成员变量。本应多个 Controller 复用同一个 Service,多个 Service 复用同一个 DAO。现在变成了一个
    Controller创建多个重复的 Service,多个 Service 又创建了多个重复的 DAO。

  2. 代码变更代价大
    很多时候创建一个组件,比如 DAO 对象要依赖一个这样的数据源组件。更改类或者实现类需要改动多个地方,创建和配置组件工作也很繁琐。

ublic class UserDaoImpl implements UserDao{
    private MyDataSource dataSource;

    public UserDaoImpl() {
        // 构造数据源
        dataSource = new MyDataSource("jdbc:mysql://localhost:3306/test", "root", "password");
        // 进行一些其他配置
        dataSource.setInitiaSize(10);
        dataSource.setMaxActive(100);
        // ...省略更多配置项
    }
}


IoC是什么

IoC就是Inversion of Control,控制反转。在Java开发中,IoC意味着将你设计好的交给系统去控制,而不是在你的类内部控制。这称为控制反转。
**IoC 容器就是管理类(对象)的,**交由容器管理后的对象称为Bean。而调用组件直接获取Bean即可。

@Component
public class UserServiceImpl implements UserService{
    @Autowired // 获取 Bean
    private UserDao userDao;
}

DI机制?
依赖注入(Dependecy Injection)
控制反转和依赖注入是一体两面,都是同一种开发模式的表现形式。
DI(Dependency Injection) — IOC 的一种实现手段: 即组件以一些预先定义好的方式(例如: setter 方法)接受来自如容器的资源注入. 相对于 IOC 而言,这种表述更直接(容器向组件注入资源,方式有:属性注入、构造器注入。传统的资源查找方式要求组件向容器发起请求查找资源. 作为回应, 容器适时的返回资源。

=============================
具体的讲:当某个角色 需要另外一个角色协助的时候,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中
创建被调用者的工作不再由调用者来完成,因此称为控制反转。创建被调用者的工作由spring来完成,然后注入调用者 因此也称为依赖注入。
spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。 设置注入的优点:直观,自然
构造注入的优点:可以在构造器中决定依赖关系的顺序。


IoC是代理模式的一种实现。代理模式的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

依赖注入的方式
  1. Autowired/resource 等等 (可以再属性、构造器、sertter上标注)
  2. setter方法注入(xml中的利用property标签,实际是调用sertter方法)
  3. 构造器注入
  4. 静态/实例工厂(只找到xml里面的用法)



OOP

面向对象编程(Object-oriented programming)的三大特性:封装、继承、多态。 OOP 的局限性主要是:核心业务逻辑可复用但辅助逻辑复用难

当有重复代码出现时,可以就将其封装出来然后复用。我们通过分层、分包、分类来规划不同的逻辑和职责。复用的都是核心业务逻辑,并不能复用一些辅助逻辑, 比如:日志记录、性能统计、安全校验、事务管理,等等。

OOP 是至上而下的编程方式,犹如一个树状图,A调用B、B调用C,或者A继承B、B继承C。这种方式对于业务逻辑来说是合适的,通过调用或继承以复用。而辅助逻辑就像一把闸刀横向贯穿所有方法,
在这里插入图片描述
每条横线仿佛切开了 OOP 的树状结构,每一层都会执行相同的辅助逻辑,这些辅助逻辑称为层面或者切面。

切面逻辑的难点不是不修改原有业务,而是对所有业务生效。对一个业务类增强就得新建一个代理类,对所有业务增强,每个类都要新建代理类。但有些类压根就不需要代理类。面向切面编程(Aspect-oriented programming,缩写为 AOP)正是为了解决这一问题而诞生的技术。



AOP是什么

面向切面编程(AOP)是以另一个角度来考虑程序结构,通过分析程序结构的关注点来完善面向对象编程(OOP)。OOP将应用程序分解成各个层次的对象,而AOP将程序分解成多个切面。spring AOP 只实现了方法级别的连接点,在J2EE应用中,AOP拦截到方法级别的操作就已经足够。

AOP 技术,让我们能够不修改原有代码,便能让切面逻辑在所有业务逻辑中生效。

@Aspect // 声明一个切面
@Component
public class MyAspect {
    // 原业务方法执行前
    @Before("execution(public void com.rudecrab.test.service.*.doService())")
    public void methodBefore() {
        System.out.println("===AspectJ 方法执行前===");
    }

    // 原业务方法执行后
    @AfterReturning("execution(* com.rudecrab.test.service..doService(..))")
    public void methodAddAfterReturning() {
        System.out.println("===AspectJ 方法执行后===");
    }
}

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式, 引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

面向切面编程(aop)是对面向对象编程(oop)的补充,
面向对象编程将程序分解成各个层次的对象,面向切面编程将程序运行过程分解成各个切面。
AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象,
是对应用执行过程中的步骤进行抽象,,从而获得步骤之间的逻辑划分。

AOP面向切面编程在spring中主要表现哎
1、面向切面提供声明式事务管理
2、spring支持用户自定义的切面
因此可以实现编程各个步骤之间良好隔离性和源代码之间的无关性。



补充和总结

在这里插入图片描述

IoC 解决了以下问题:

创建了许多重复对象,造成大量资源浪费;
更换实现类需要改动多个地方;
创建和配置组件工作繁杂,给组件调用方带来极大不便。

AOP解决了以下问题:

切面逻辑编写繁琐,有多少个业务方法就需要编写多少次。

文章参考学习自

https://zhuanlan.zhihu.com/p/349386138?utm_source=wechat_session&utm_medium=social&utm_oi=627454633166114816

https://www.jianshu.com/p/bceaccfa3b5d

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值