Spring的两个核心特性:

  • 依赖注入(dependency injection,DI)
  • 面向切面编程(aspect oriented programming,AOP)

依赖注入(dependency injection,DI)

  • 没有使用依赖注入时:以前每个POJO(Plain Ordinary Java Object,简单的Java对象)在创建的时候会主动的去获取依赖。从代码上的体现是一个类中有实例化另一个类的对象(耦合度高)。我们需要将相互协作的对象引用赋给它。
  • 三种依赖注入方式:setter方法注入,构造器注入,接口注入(就是在接口中声明一个方法,参数是依赖的对象)。
  • 依赖注入作用:将各个相互协作的模块代码保持松散耦合。
  • 下面我们通过几个简单的类来了解一下依赖注入:

先声明两个接口People与Fruit。

public interface People {// people接口
void eat();
} public interface Fruit {// 水果接口
void speak();
}

接下来是分别实现他们的类Watermelon与Student。

public class Watermelon implements Fruit{// 西瓜类
@Override
public void speak() {
System.out.println("我是西瓜,我要被吃掉了!");
}
} public class Student implements People {// 学生类
private Fruit fruit; public Student(Fruit fruit) {// 构造器注入依赖的对象
this.fruit = fruit;
} @Override
public void eat() {
fruit.speak();
}
}

到这里我们可以看出Student类依赖Watermelon类。当调用Student的eat方法时需要调用Watermelon的speak方法。

我们接下来用XML对这两个应用组件进行装配(wiring)。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--水果声明为Spring的bean-->
<bean id="fruit" class="com.qsh.springaction.Watermelon"/>
<!--人声明为Spring的bean-->
<bean id="people" class="com.qsh.springaction.Student">
<constructor-arg ref="fruit"/>
</bean>
</beans>

最后我们进行测试。用spring上下文全权负责对象的创建和组装。

public class TestEat {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("eat.xml");
People people = context.getBean(People.class);
people.eat();
context.close();
}
}

测试结果。

面向切面编程(aspect oriented programming,AOP)

  • 是什么:促使软件系统实现关注点分离的一项技术。系统由许多不同组件构成,每个组件负责一块特定功能。除了实现自身核心功能外,这些组件还承担着额外职责,如日志,事务管理和安全这样的系统服务,这样的系统服务被称为横切关注点。因为他们会横跨多个组件。
  • 作用:有助于横切关注点与它们所影响的对象之间的解耦。
  • 个人理解:每个组件除了实现自身的功能,还需要实现其他的如事物管理等功能(称为横切关注点)。我们将这功能单独抽取出来成一个模块,每个组件在工作的过程中,这个模块神不知鬼不觉的为每个组件实现额外功能。
  • 个人理解的切面图:应用组件:实现各自功能的代码。横切关注点:每个组件的额外业务,相同的代码。切面:将横切关注点模块化出来的一个类。连接点:应用执行时能够插入切面的点(超级多)切点:匹配其中一个或多个连接点。

  • 通过几段代码讲解AOP:

我们还是有上面的Student 和 Watermelon类。需要新增加一个Action类,就是一会的切面。

public class Action {// 行为类

    public void beforeEat() {
System.out.println("吃前拿刀,嚓嚓嚓");
} public void afterEat() {
System.out.println("吃后洗手,哗哗哗");
}
}

需要在XML中加入Spring AOP命名空间,将Action方法声明为Spring的bean,然后切面引用这个bean。切点为student的eat方法,在切点前后加入前置通知和后置通知。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> <!--水果声明为Spring的bean-->
<bean id="fruit" class="com.qsh.springaction.Watermelon"/>
<!--人声明为Spring的bean-->
<bean id="people" class="com.qsh.springaction.Student">
<constructor-arg ref="fruit"/>
</bean>
<!--行为声明为Spring的bean-->
<bean id="action" class="com.qsh.springaction.Action"/> <!--用spring aop的命名空间把Action声明为一个切面-->
<aop:config>
<!--引用Action的bean-->
<aop:aspect ref="action">
<!--声明Student的eat方法为一个切点-->
<aop:pointcut id="eating" expression="execution(* *.eat(..))"/>
<!--前置通知,在调用eat方法前调用Action的beforeEat方法-->
<aop:before pointcut-ref="eating" method="beforeEat"/>
<!--后置通知,在调用eat方法后调用Action的afterEat方法-->
<aop:after pointcut-ref="eating" method="afterEat"/>
</aop:aspect>
</aop:config>
</beans>

运行结果为:

5分钟简述Spring中的DI与AOP的更多相关文章

  1. 如何快速理解Spring中的DI和AOP

    前言 Spring框架通过POJO最小侵入性编程.DI.AOP.模板代码手段来简化了Java 开发,简化了企业应用的开发.POJO和模板代码相对来说好理解,本篇重点解读下DI和AOP. 一 DI DI ...

  2. 详谈 Spring 中的 IOC 和 AOP

    这篇文章主要讲 Spring 中的几个点,Spring 中的 IOC,AOP,下一篇说说 Spring 中的事务操作,注解和 XML 配置. Spring 简介 Spring 是一个开源的轻量级的企业 ...

  3. Spring中基于xml的AOP

    1.Aop 全程是Aspect Oriented Programming 即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术.Aop是oop的延续,是软件开发中的 一个热点 ...

  4. 用通俗的语言解释 Spring 中的 DI 、IOC 和AOP概念

    DI 所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B.所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调用B,如果不倒置,意思就是 ...

  5. 一分钟掌握Spring中bean的生命周期!

    Spring 中bean 的生命周期短暂吗? 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean 的别名只能维持 ...

  6. 理解Spring中的IOC和AOP

    我们是在使用Spring框架的过程中,其实就是为了使用IOC,依赖注入和AOP,面向切面编程,这两个是Spring的灵魂. 主要用到的设计模式有工厂模式和代理模式 IOC就是典型的工厂模式,通过ses ...

  7. spring中基于注解使用AOP

    本文内容:spring中如何使用注解实现面向切面编程,以及如何使用自定义注解. 一个场景 比如用户登录,每个请求发起之前都会判断用户是否登录,如果每个请求都去判断一次,那就重复地做了很多事情,只要是有 ...

  8. 在Spring中使用AspectJ实现AOP

    在Spring中,最常用的AOP框架是AspectJ,使用AspectJ实现AOP有2种方式: 基于XML的声明式AspectJ 基于注解的声明式AspectJ 基于XML的声明式AspectJ 1. ...

  9. 解释Spring中IOC, DI, AOP

    oc就是控制翻转或是依赖注入.通俗的讲就是如果在什么地方需要一个对象,你自己不用去通过new 生成你需要的对象,而是通过spring的bean工厂为你长生这样一个对象.aop就是面向切面的编程.比如说 ...

随机推荐

  1. alibaba的FastJson(高性能JSON开发包) json转换

    http://www.oschina.net/code/snippet_228315_35122 class User{ private int id; private String name; pu ...

  2. Centos7 安装PHP7版本及php-fpm,redis ,php-redis,hiredis,swoole 扩展安装

    ============================PHP7.1 ========================================= 1. 更换rpm 源,执行下面两个 rpm - ...

  3. 3、一、Introduction(入门):2、Device Compatibility(设备兼容性)

    2.Device Compatibility(设备兼容性)   Android is designed to run on many different types of devices, from ...

  4. php 启动服务器监听

    使用命令 php -S 域名:端口号 -t 项目路径 截图如下: 原本是通过localhost访问的 现在可以通过 127.0.0.1:8880 访问 此时命令行终端显示如下:

  5. Unity3D UGUI Shader画一个圆环

    Shader "Unlit/NewUnlitShader" { Properties { _MainTex ("Texture", 2D) = "wh ...

  6. C# 反射(Reflection)

    什么是反射 发射是 .net framework 提供的一个帮助类库,用于读取和使用元数据. 用到的类:System.Reflection,System.Type.System.Type 类对于反射起 ...

  7. 我是怎样使用javassist将代码注入到帝国OL并进行调试的

    帝国OL是拉阔一款手机网络游戏(腾讯也有代理),我在中学时代玩儿过. 帝国OL还维护着KJava版本游戏客户端,这意味着我们可以在PC端使用模拟器玩儿游戏. 不过这篇文章我主要是关注如何通过代码注入拦 ...

  8. ORM正向和反向查询

    表结构 from django.db import models # Create your models here.class Publisher(models.Model): id = model ...

  9. Linux搭建Socks5代理服务器

    下面笔者将用SS5在亚马逊云服务器上的Linux搭建一台Socks5 Proxy Server,具体过程如下: 1.首先,编译安装SS5需要先安装一些依赖组件 yum -y install gcc g ...

  10. c语言中的左移和右移

    先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例如: int i = 1;i = i << 2;  //把i里的值左移2位 也就是说,1的2进制是00 ...