spring ioc和aop

680 阅读8分钟

一、spring概述

1. spring是什么

Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:
反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。 

2. spring发展历程

1997 年 IBM 提出了 EJB 的思想,EJB最初的设计思想考虑的是为分布式的应用服务的,分布式是针对大型应用构造的跨平台的协作计算,EJB最初的目的就是为这种计算服务的。但是软件发展到目前为止,大多数应用不需要采用分布式的解决方案,因此用EJB显得太臃肿了。Spring的出现恰恰为了解决这个问题。
1998 年,SUN 制定开发标准规范 EJB1.0(Enterprise Java Beans)
1999 年,EJB1.1 发布
2001 年,EJB2.0 发布
2003 年,EJB2.1 发布
2006 年,EJB3.0 发布
Rod Johnson(spring 之父
Expert One-to-One J2EE Development without EJB(2004)阐述了 J2EE 开发不使用 EJB 的解决方式(Spring 雏形)
2017 年 9 月份发布了 spring 的最新版本 spring 5.0 通用版(GA)

3. spring的优势

  • 低侵入 / 低耦合 (降低组件之间的耦合度,实现软件各层之间的解耦)
  • 声明式事务管理(基于切面和惯例)
  • 方便集成其他框架(如MyBatis、Hibernate)
  • 降低 Java 开发难度
  • Spring 框架中包括了 J2EE 三层的每一层的解决方案(一站式)
  • 4. spring能帮我们做什么

    ①.Spring 能帮我们根据配置文件创建及组装对象之间的依赖关系
    ②.Spring 面向切面编程能帮助我们无耦合的实现日志记录,性能统计,安全控制。
    ③.Spring非常简单的帮我们管理数据库事务
    ④.Spring提供了与第三方数据访问框架(如Hibernate、JPA)无缝集成,而且自己也提供了一套JDBC访问模板来方便数据库访问。
    ⑤.Spring 还提供与第三方Web(如Struts1/2、JSF)框架无缝集成,而且自己也提供了一套Spring MVC框架,来方便web层搭建。
    ⑥.Spring方便的与Java EE(如Java Mail、任务调度)整合,与更多技术整合(比如缓存框架)

    5. spring体系结构


  • Data Access/Integration层包含有JDBC、ORM、OXM、JMS和Transaction模块。
  • Web层包含了Web、Web-Servlet、WebSocket、Web-Porlet模块。
  • AOP模块提供了一个符合AOP联盟标准的面向切面编程的实现。
  • Core Container(核心容器): 包含有Beans、Core、Context和SpEL模块。
  • Test模块支持使用JUnit和TestNG对Spring组件进行测试。

  • 二、ioc的概念和作用

    1. 耦合的概念

    不使用spring之前代码的写法:

    public class AccountServiceImpl implements IAccountService {
      private IAccountDao accountDao = new AccountDaoImpl();
    } 

    注册驱动的两种写法:

    DriverManager.registerDriver(new com.mysql.jdbc.Driver());
    Class.forName("com.mysql.jdbc.Driver");

    存在问题:创建合作对象的主动权在自己手上,自己需要哪个合作对象,就主动去创建,创建合作对象的主动权和创建时机是由自己把控的,而这样就会使得对象间的耦合度高了,并且是紧密耦合在一起。

    如何解耦:应该做到,编译期不依赖,运行时才依赖。

    2. IoC 是什么

    IoC:Inverse of Control(控制反转)

    • 读作 “反转控制”,更好理解,不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
    • 正控:若要使用某个对象,需要自己去负责对象的创建
    • 反控:若要使用某个对象,只需要从 Spring 容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架

    传统程序设计都是主动去创建相关对象然后再组合起来:



    当有了IOC的容器后,在客户端类中不再主动去创建这些对象了


    3. IoC 和DI

    DI—Dependency Injection,即“依赖注入”:由容器在运行期动态的将某个依赖关系注入到组件之中。依赖注入(DI)和控制反转(IOC)是从不同的角度的描述的同一件事情,就是指通过引入IOC容器,利用依赖关系注入的方式,实现对象之间的解耦。

    ioc 控制反转,指将对象的创建权,反转到Spring容器 
    DI 依赖注入,指Spring创建对象的过程中,将对象依赖属性通过配置进行注入

    4. IoC 如何实现

    1. 读取标注或者配置文件
    2. 使用反射的API,基于类名实例化对应的对象实例
    3. 将对象实例,查看是否有依赖对象,创建依赖实例,注入到目标对象

    三、aop概念和作用

    1. 一个例子

    //转账
    public void transfer() {
    1、查询两个账户信息
    2、转出账户减钱,更新转出账户
    3、转入账户加钱,更新转入账户
    }
    当我们执行时,如果第3不执行有异常,就会出现转入、转出账户金额不一致问题。

    解决方法:给转账方法增加事务控制。

    //转账
    public void transfer() {
     try {
      TransactionManager.beginTransaction();
      1、查询两个账户信息
      2、转出账户减钱,更新转出账户
      3、转入账户加钱,更新转入账户 
      TransactionManager.commit();
     } catch (Exception e) {
      TransactionManager.rollback();
     } finally {
      TransactionManager.release();
     } 
    }

    新的问题

    实际的项目中这种业务层实现类可能有十几个甚至几十个,导致业务层方法变得十分臃肿,里面充斥着很多重复代码。并且业务层方法和事务控制方法耦合了。试想一下,如果我们此时提交,回滚,释放资源中任何一个方法名变更,都需要修改业务层的代码。

    2. AOP概念

    AOP (Aspect Oriented Programming),面向切面编程。

    首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能。

    • 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务
    • 所谓的周边功能,比如性能统计,日志,事务管理等等

    周边功能在 Spring 的面向切面编程AOP思想里,即被定义为切面

    在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP。

    3. AOP 的作用及优势

    AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码降低模块间的耦合度,并有利于未来的可拓展性和可维护性。这样的做法,对原有代码毫无入侵性,把和主业务无关的事情,放到代码外面去做。

    作用:
    在程序运行期间,不修改源码对已有方法进行增强。
    优势:
    减少重复代码
    提高开发效率

    4. AOP实现方式

    什么是代理模式(Proxy)

    定义:给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用

    在代理模式中,是需要代理对象和目标对象实现同一个接口

    使用代理模式的原因就是,在不改变目标对象方法的情况下对方法进行增强,比如,我们希望对方法的调用增加日志记录,或者对方法的调用进行拦截,等等...

    静态代理的缺陷:接口与代理类是1对1的,有多个接口需要代理,就需要新建多个代理类,繁琐,类爆炸


    基于接口的动态代理
    提供者:JDK 官方的 Proxy 类。
    要求:被代理类最少实现一个接口。 
    基于子类的动态代理
    提供者:第三方的 CGLib

    要求:被代理类不能用 final 修饰的类(最终类)。 
    Spring AOP就是基于动态代理的,如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用JDK Proxy去进行代理了),这时候Spring AOP会使用Cglib,生成一个被代理对象的子类,来作为代理。



    四、spring中的aop

    1. AOP相关术语

    Joinpoint(连接点):
    所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的连接点。
    Pointcut(切入点):
    所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
    Advice(通知/增强):
    所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。
    通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
    Introduction(引介):
    引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field。
    Target(目标对象):
    代理的目标对象。
    Proxy(代理):
    一个类被 AOP 织入增强后,就产生一个结果代理类。
    Aspect(切面):
    是切入点和通知(引介)的结合

    2. 通知的执行顺序问题

    通知类型的执行先后顺序问题:前置通知>最终通知>后置通知

    建议使用环绕通知