简单理解Spring之IOC和AOP及代码示例

Spring是一个开源框架,主要实现两件事,IOC(控制反转)和AOP(面向切面编程)。

IOC

控制反转,也可以称为依赖倒置。

所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B。所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调用B,如果不倒置,意思就是A主动获取B的实例:Bb=newB(),这就是最简单的获取B实例的方法(当然还有各种设计模式可以帮助你去获得B的实例,比如工厂、Locator等等),然后你就可以调用b对象了。所以,不倒置,意味着A要主动获取B,才能使用B;到了这里,就应该明白了倒置的意思了。倒置就是A要调用B的话,A并不需要主动获取B,而是由其它人自动将B送上门来。

所谓控制反转,就是控制权的转移,举例说明:一个人要开车,正常情况下,人应该自己去找车,而实现控制反转后,人就不需要考虑车从哪里来了,直接开就行了,人就把找车的控制权转移给了别的对象。体会一下下面的代码

先定义一个接口Car

public interface Car {
  void go();
}

定义两种车

public class Benz implements Car {

  public void go() {
    System.out.println("benz go......");
  }
}

public class BMW implements Car{

  public void go() {
    System.out.println("bmw go......");
  }
}

下面是人开车

public class Person {

  Car car=new Benz();

  void DriveCar(){
    System.out.println("begin drive");
    car.go();
  }
}

这是正常的代码控制流程,人想要开车,就要自己去实例化一辆车。但是,这样子的话,这个人就只能开一种车。怎么样才能让这个人能开各种车呢,就是要实现控制反转,也就是说,人不再去自己实例化车了,那人怎样得到车的对象呢?我们可以通过依赖注入(Dependency Injection,简称DI)的方式来让人得到车的对象,从而实现控制反转。所以,我们要修改Person类

public class Person {

  Car car=null;
  public Person(Car car){
    this.car=car;
  }

  void driveCar(){
    System.out.println("begin drive");
    car.go();
  }
}

现在的Person类已经不自己实例化车的对象了,而是通过构造函数来获得车的对象,所以,这个类就可以开各种车了,只要这个车实现了Car接口就可以。看一下如何使用Person类

public static void main(String[] args) {
  Person p=new Person(new Benz());
  p.driveCar();
}

现在的Person类可以开不止一种车,只要你通过构造函数传递进来。在这个例子中,Car对象就是Person类的依赖,当我们实例化Person类时,将一个Car的实例传递给Person类,就是依赖注入,我们的Person类从而实现了控制反转。

控制反转到底反转了什么?有种说法是这样的:所谓控制反转,反转的是获取对象依赖的过程。控制权反转后,获取依赖对象的过程由自身管理变为由IOC容器注入。

Spring实现依赖注入的方式

在上面的这行代码中Person p=new Person(new Benz());,我们通过手动的方式new了一个Benz()的对象,然后将其注入到Person类中。而Spring不这么干,因为Spring觉得,你这行代码实例化了一个具体的Benz类,如果你以后想要在这里实例化一个BMW类的话,岂不是要修改代码?那我干脆写到配置文件里好了,即便你将来要该注意,至少不需要修改代码,于是就有了下面的配置

<beans>
  <bean id="car" class="com.XXX.Benz" />
  <bean id="person" class="com.XXX.Person" >
    <property name="car" ref="car" />
  <bean/>
</beans>

然后,Spring再提供一些机制,从配置文件中获取Person类的对象时,它所以来的car对象会被装配进来,而person对象不需要关心到底是哪个具体的类被传递进来了。所以,Spring作为一个IOC框架主要做了两步:创建对象和组装对象之间的关系。

AOP

AOP(Aspect Oriented Programming)是面向切面编程,下面我来举例说明什么是切面。在一个完整的网站项目中,很多模块都需要做日志记录,很多地方都需要做登录判断,很多地方都需要做异常处理。日志记录,登录判断,异常处理等这些逻辑,就是所谓的切面。假设我将这些切面的逻辑写得到处都是,那么代码的可维护性就可想而知了。AOP就是为了实现关注点分离,将这些切面的逻辑抽出来写到单独的类中,然后再想办法将他们与一般的模块组装到一块来执行,普通模块甚至都不知道他们已经和切面组装到一块了。

面向切面编程的目标就是分离关注点。什么是关注点呢?就是你要做的事,就是关注点。假如你是个公子哥,没啥人生目标,天天就是衣来伸手,饭来张口,整天只知道玩一件事!那么,每天你一睁眼,就光想着吃完饭就去玩(你必须要做的事),但是在玩之前,你还需要穿衣服、穿鞋子、叠好被子、做饭等等等等事情,这些事情就是你的关注点,但是你只想吃饭然后玩,那么怎么办呢?这些事情通通交给别人去干。在你走到饭桌之前,有一个专门的仆人A帮你穿衣服,仆人B帮你穿鞋子,仆人C帮你叠好被子,仆人C帮你做饭,然后你就开始吃饭、去玩(这就是你一天的正事),你干完你的正事之后,回来,然后一系列仆人又开始帮你干这个干那个,然后一天就结束了!

AOP的好处就是你只需要干你的正事,其它事情别人帮你干。也许有一天,你想裸奔,不想穿衣服,那么你把仆人A解雇就是了!也许有一天,出门之前你还想带点钱,那么你再雇一个仆人D专门帮你干取钱的活!这就是AOP。每个人各司其职,灵活组合,达到一种可配置的、可插拔的程序结构。

从Spring的角度看,AOP最大的用途就在于提供了事务管理的能力。事务管理就是一个关注点,你的正事就是去访问数据库,而你不想管事务(太烦),所以,Spring在你访问数据库之前,自动帮你开启事务,当你访问数据库结束之后,自动帮你提交/回滚事务!

看下面的代码,看不懂没关系

<bean id="audience" class="com.springinaction.springidol.Audience" />
<aop:config>
 <aop:aspect ref="audience">
  <aop:pointcut id="performance" expression=
    "execution(* com.springinaction.springidol.Performer.perform(..))"
    />

  <aop:before
    pointcut-ref="performance"
    method="takeSeats" /> <!--<co id="co_refPointcut"/>-->
  <aop:before
    pointcut-ref="performance"
    method="turnOffCellPhones" /> <!--<co id="co_refPointcut"/>-->
  <aop:after-returning
    pointcut-ref="performance"
    method="applaud" /> <!--<co id="co_refPointcut"/>-->
  <aop:after-throwing
    pointcut-ref="performance"
    method="demandRefund" /> <!--<co id="co_refPointcut"/>-->
 </aop:aspect>
</aop:config>

上面配置的大概意思是,当Performer.perform方法将要发生时,Spring框架中的代理会将目标方法(Performer.perform())拦截下来,执行目标方法前先执行Audience.takeSeats()和Audienceturn.OffCellPhones()方法,然后运行目标方法,当目标方法执行完毕返回时,再运行Audienceturn.applaud()方法。如果目标方法不幸抛出了异常,代理会运行Audienceturn.demandRefund()方法。总之,Spring的代理类全方位地监控了目标方法的执行,而目标方法只专注于自己的事情,甚至都不知道代理类的存在。

总结

以上就是本文关于简单理解Spring之IOC和AOP及代码示例的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:

Spring的Ioc模拟实现详细介绍

Spring AOP拦截-三种方式实现自动代理详解

如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

(0)

相关推荐

  • 详谈Spring对IOC的理解(推荐篇)

    一.IOC控制反转和DI依赖注入 1.控制反转,字面可以理解为:主动权的转移,原来一个应用程序内的对象是类通过new去主动创建并实例化的,对对像创建的主动权在程序代码中.程序不仅要管理业务逻辑也要管理对的象创建和依赖关系.这是很累的,也跟软件工程 "低耦合高内聚" 的概念不十分符合. 有了spring的ioc容器之后,对象的实例化和依赖关系管理都由IOC容器进行统一管理,主体类只要依赖ioc容器就够了,需要啥,容器会给他注入进去,也就是只要声明对象不用再主动去new,ioc容器帮忙把相

  • Spring的Ioc模拟实现详细介绍

    简单来说就是当自己需要一个对象的时候不需要自己手动去new一个,而是由其他容器来帮你提供:Spring里面就是IOC容器. 例如: 在Spring里面经常需要在Service这个装配一个Dao,一般是使用@Autowired注解:类似如下 public Class ServiceImpl{ @Autowired Dao dao; public void getData(){ dao.getData(); } 在这里未初始化Dao直接使用是会报出空指针异常的,那么在Spring里面的做法就是通过反

  • spring的IoC和DI详解

    这里先来简单介绍下IoC和DI的区别: IOC:翻译过来是控制反转,将对象的创建权由Spring管理,HelloService不需要自己去创建,Spring可以帮你创建. DI:依赖注入,在我们创建对象的过程中,把对象依赖的属性注入到我们的类中. 我们现在编写的类是没有其它的属性的,如果你学过UML这种设计的话,面向对象中对象中的几种关系 简单来书,IoC更像是一种思想,DI是一种行为. 另一种说法是,ioc是目的,di是手段.ioc是指让生成类的方式由传统方式(new)反过来,既程序员不调用n

  • 浅谈springioc实例化bean的三个方法

    1.构造器 也就是在上一篇讲的那个例子,调用默认的无参构造函数 2.静态工厂方法 1)创建需要执行的方法的类 public class HelloWorld { public HelloWorld(){ System.out.println("aaaa"); } public void hello(){ System.out.println("hello world"); } } 2)创建静态工厂 public class HelloWorldFactory { p

  • Spring中IoC优点与缺点解析

    本文为大家分享了Spring中IoC优点与缺点,供大家参考,具体内容如下 1. 优点 我们知道,在Java基本教程中有一个定律告诉我们:所有的对象都必须创建:或者说:使用对象之前必须创建,但是现在我们可以不必一定遵循这个定律了,我们可以从Ioc容器中直接获得一个对象然后直接使用,无需事先创建它们. 这种变革,就如同我们无需考虑对象销毁一样:因为Java的垃圾回收机制帮助我们实现了对象销毁:现在又无需考虑对象创建,对象的创建和销毁都无需考虑了,这给编程带来的影响是巨大的. 我们从一个简单例子开始,

  • 简单实现Spring的IOC原理详解

    控制反转(InversionofControl,缩写为IoC) 简单来说就是当自己需要一个对象的时候不需要自己手动去new一个,而是由其他容器来帮你提供:Spring里面就是IOC容器. 例如: 在Spring里面经常需要在Service这个装配一个Dao,一般是使用@Autowired注解:类似如下 public Class ServiceImpl{ @Autowired Dao dao; public void getData(){ dao.getData(); } 在这里未初始化Dao直接

  • 基于springioc bean 的几个属性介绍

    1.lazy-init="false" 默认值为false,指的是bean的创建时机的spring容器一启动就会加载这些类.有点是及时发现bean的相关错误,因为spring容器启动,bean也都会创建完毕,如果bean有什么差错都会报出,缺点就是如果bean对象的开销较大,那会提前占用内存. 如果设置为true,则等到spring容器去获取该bean的对象时才会创建.优缺点与false相反 2.scope="singleton" 默认值就是singleton,指的

  • spring中ioc是什么

    IoC--Inversion of Control,控制反转 在Java开发中,IoC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制.IoC是一种让服务消费者不直接依赖于服务提供者的组件设计方式,是一种减少类与类之间依赖的设计原则. DI--Dependency Injection(依赖注入) 即组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中. 依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活.

  • 简单理解Spring之IOC和AOP及代码示例

    Spring是一个开源框架,主要实现两件事,IOC(控制反转)和AOP(面向切面编程). IOC 控制反转,也可以称为依赖倒置. 所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B.所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调用B,如果不倒置,意思就是A主动获取B的实例:Bb=newB(),这就是最简单的获取B实例的方法(当然还有各种设计模式可以帮助你去获得B的实例,比如工厂.Locator等等),然后你就可以调用b对象了.

  • 简单理解插入排序算法及Swift版的代码示例

    算法思想 插入排序的方式类似平时打扑克牌的时候排序自己手中的扑克牌.开始时,我们左手中没有牌,桌上有洗好的扑克牌,我们抓取一张扑克牌并放入左手的正确位置.为了找到一张扑克牌的正确位置,我们从右到左将它与手中的每张牌进行比较,左手上的牌总是排序好的,而这些牌原来都是桌上牌堆中顶部的牌,当我们抓完牌时,左手中的牌自然是有顺序的. 之所以叫插入排序,不是为别的,正是因为该算法的核心就是将无序的元素插入排好序的部分. 插入排序的核心思想即在于划分已排序和未排序,将每个待排序的元素逐个与已排序的元素比较,

  • Spring中IOC和AOP的深入讲解

    前言 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来.它是为了解决企业应用开发的复杂性而创建的.Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情.然而,Spring的用途不仅限于服务器端的开发.从简单性.可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益

  • Spring核心IoC和AOP的理解

    spring 框架的优点是一个轻量级笔记简单易学的框架,实际使用中的有点优点有哪些呢! 1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能 5.容器提供了众多的辅助类,能加快应用的开发 6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等 7.spring属于低侵入式设计,代码的污染极低 8.独立于

  • Java的Spring框架下的AOP编程模式示例

    Spring框架的关键组件是面向方面编程(AOP)框架.面向方面的编程不仅打破程序逻辑分成不同的部分称为所谓的担忧.跨越多个点的应用程序的功能被称为横切关注点和这些横切关注点是从应用程序的业务逻辑概念上区分开来.还有像日志记录,审计,声明性事务,安全性和高速缓存等方面的各种常见的好例子 模块化的OOP中的关键单元是类,而在AOP中模块化的单元则是切面.依赖注入可以帮助你从对方解耦应用程序对象和AOP可以帮助你从他们影响的对象分离横切关注点. AOP是一样的编程语言如Perl,.NET,Java和

  • 简单了解Spring循环依赖解决过程

    这篇文章主要介绍了简单了解Spring循环依赖解决过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 前言 说起Spring中循环依赖的解决办法,相信很多园友们都或多或少的知道一些,但当真的要详细说明的时候,可能又没法一下将它讲清楚.本文就试着尽自己所能,对此做出一个较详细的解读.另,需注意一点,下文中会出现类的实例化跟类的初始化两个短语,为怕园友迷惑,事先声明一下,本文的实例化是指刚执行完构造器将一个对象new出来,但还未填充属性值的状态,而

  • 简单了解Spring Cloud Alibaba相关知识

    这篇文章主要介绍了简单了解Spring Cloud Alibaba相关知识,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 官方github地址 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案.此项目包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务. 主要功能 服务限流降级:默认支持 WebServlet.WebFlux, OpenFeign

  • Spring IOC简单理解及创建对象的方式

    spring框架 控制反转(Inversion on Control)在spring框架里面,一般交给Spring容器,这叫控制反转 什么是控制反转呢? 先来说一下控制正转, class Demo{ Student student = new Student(); } 简单地来说就是自己去创建对象,需要什么对象,就创建什么对象,实在当前文件中创建出来的,自己new出来的,这就叫做"控制正转" 那么控制反转是什么: 就是跟控制正转反着来,就是我需要的对象,我不需要自己new创建出来,我只

  • Spring IOC和aop的原理及实例详解

    这篇文章主要介绍了Spring IOC和aop的原理及实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架.特点是面向接口编程,松耦合. 1:IOC(控制反转) 别名(DI:依赖注入) 首先来一段ioc的实现原来代码: public class ClassPathXmlApplicationContext implements BeanFactory { privat

随机推荐