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拦截-三种方式实现自动代理详解

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

 

简单理解Spring之IOC和AOP及代码示例的更多相关文章

  1. Spring 的 IOC 和 AOP 的理解

    Spring 的 IOC 和 AOP 的理解: https://www.jianshu.com/p/bf1adc3b75e6 对Spring的核心(AOP和IOC)的理解(大白话) https://w ...

  2. Spring的IOC和AOP之深剖

    今天,既然讲到了Spring 的IOC和AOP,我们就必须要知道 Spring主要是两件事: 1.开发Bean:2.配置Bean.对于Spring框架来说,它要做的,就是根据配置文件来创建bean实例 ...

  3. Spring 的IOC和AOP总结

    Spring 的IOC和AOP IOC 1.IOC 许多应用都是通过彼此间的相互合作来实现业务逻辑的,如类A要调用类B的方法,以前我们都是在类A中,通过自身new一个类B,然后在调用类B的方法,现在我 ...

  4. Spring中IOC和AOP的详细解释(转)

    原文链接:Spring中IOC和AOP的详细解释 我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入,和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂 ...

  5. Spring 的IOC 和Aop

    Spring 的IOC 和Aop

  6. Spring入门IOC和AOP学习笔记

    Spring入门IOC和AOP学习笔记 概述 Spring框架的核心有两个: Spring容器作为超级大工厂,负责管理.创建所有的Java对象,这些Java对象被称为Bean. Spring容器管理容 ...

  7. 展开说说,Spring Bean IOC、AOP 循环依赖

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 延迟满足能给你带来什么? 大学有四年时间,但几乎所有人都是临近毕业才发现找一份好工作 ...

  8. spring的IOC和AOP

     spring的IOC和AOP 1.解释spring的ioc? 几种注入依赖的方式?spring的优点? IOC你就认为他是一个生产和管理bean的容器就行了,原来需要在调用类中new的东西,现在都是 ...

  9. spring的IOC和AOP详细讲解

    1.解释spring的ioc? 几种注入依赖的方式?spring的优点? IOC你就认为他是一个生产和管理bean的容器就行了,原来需要在调用类中new的东西,现在都是有这个IOC容器进行产生,同时, ...

随机推荐

  1. map函数的应用

    map函数在Python中的应用 函数介绍: map() 会根据提供的函数对指定序列做映射. map(function, iterable, ...) 第一个参数function 以参数序列中的每一个 ...

  2. JavaScript,遍历,for

    (for循环,for...in ,for...of ,forEach)(:for in总是得到数组,字符串的下标,而for of和forEach一样,是直接得到值) (forEach() 方法用于调用 ...

  3. FreeRTOS 任务挂起和恢复

    在使用RTOS的时候一个实时应用可以作为一个独立的任务.每个任务都有自己的运行环境, 不依赖于系统中其他的任务或者RTOS调度器. 任何一个时间点只能有一个任务运行,具体运行哪个任务是由RTOS调度器 ...

  4. sql server with as只能查询一次

    WITH Emp AS (SELECT acc.* FROM GXSpreadDB.dbo.gxs_account acc LEFT JOIN RYAccountsDB.dbo.AccountsInf ...

  5. 四、DDL常见操作汇总

    DDL: Data Define Language 数据定义语言,主要用来对数据库.表进行一些管理操作.如:建库.删库.建表.修改表.删除表.对列的增删改等. 一.库的管理 1.创建库 create ...

  6. Python 虚拟空间的使用

    使用虚拟环境, 可以将当前项目所使用的依赖与电脑中其他 Python 项目的依赖区分开, 避免依赖版本不匹配带来的问题, 同时也可以防止项目依赖被不当更新. mkdir myproject cd my ...

  7. VSCode之使用Settings Sync同步配置和插件

    需求背景 自己平常工作,一般在公司用公司的电脑,在家里就是自己的,但是vscode如果配置了新的内容,或者安装了新的插件,那每次都需要单独记录一下然后再重新配置一遍.使用Settings Sync插件 ...

  8. grep redis-cli command

    https://www.reddit.com/r/redis/comments/atfvqy/how_to_grep_from_monitor_command/ _------------------ ...

  9. urlrewrite与struts2结合使用基本配置

    1.更改web.xml,,,在struts2拦截器前面添加urlrewrite配置信息,,默认是forward的 <filter> <filter-name>UrlRewrit ...

  10. PostgreSQL 学习手册-模式Schema

    一个数据库包含一个或多个命名的模式,模式又包含表.模式还包含其它命名的对象,包括数据类型.函数,以及操作符.同一个对象名可以在不同的模式里使用而不会导致冲突: 比如,schema1和myschema都 ...