Spring简化Java的下一个理念:基于切面的声明式编程

3、应用切面

依赖注入的目的是让相互协作的组件保持松散耦合;而AOP编程允许你把遍布应用各处的功能分离出来形成可重用的组件

AOP面向切面编程被定义为促使应用程序分离关注点的一项技术。系统由许多不同的组件组成,每个组件除了负责某一特定的功能,还要承担额外的职责,诸如日志、事务管理和安全等等的服务经常融入到自身的核心业务逻辑中去,这些服务统称为横向关注点,因为它们总是跨越系统的各个组件。

将这些代码分散到多个组件,会导致双重复杂性:

  1. 如果要修改关注点得逻辑,必须修改各个组件的相关实现。即使你把这些关注点抽象成一个独立的模块,其他模块只是调用它的方法,但方法的调用还是会重复出现在各个模块中(耦合);
  2. 组件代码会因为那些与自身核心业务无关的代码而变得混乱。

假设你需要使用吟游诗人这个服务类来记载骑士(BraveKnight)的所有事迹,建立Minstrel(吟游诗人)类。

package com.test.knights;

public class Minstrel {
public void singBeforeQuest() {
System.out.println("Fa la la; The knight is so brave!");
} public void singAfterQuest() {
System.out.println("Tee hee he; The brave knight do a quest");
}
}

让我们做适当的调整来让BraveKnight来使用Minstrel

package com.test.knights;

public class BraveKnight implements Knight {
private Quest quest;
private Minstrel minstrel; public BraKnight(Quest quest, Minstrel minstrel) {
this.quest = quest;
this.minstrel = minstrel;
} public void embrakOnQuest() throws QuestException {
minstrel.singBeforeQuest();
quest.embrak();
minstrel.singAfterQuest();
}
}

这样达到了预期的效果:骑士做任务前执行singBeforeQuest()方法、任务后执行singAfterQuest()方法。但是管理吟游诗人真的是骑士的责任吗?骑士在依赖注入时就必须提供一个吟游诗人,这显然是不合逻辑的。吟游诗人应该自己独立出来,他有自己分内的事情。

改进,把Minstrel抽象为一个切面,你所做是是在Spring配置文件中声明它。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
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.0.xsd">
<bean id = "knight" class = "com.test.knight.BraveKnight">
<constructor-arg ref = "quest" />
</bean> <bean id = "quest" class = "com.test.knight.SlayDragonQuest" /> <!-- add -->
<bean id = "minstrel" class = "com.test.knight.Minstrel" />
<aop:config>
<aop:aspect ref="minstrel">
<aop:pointcut id="embark" expression="execution(* *.embrakOnQuest(..))" />
<aop:before pointcut-ref="embark"> method="singBeforeQuest" />
<aop:after pointcut-ref="embark"> method="singAfterQuest" />
</aop:aspect>
</aop:config>
</beans>

这里将minstrel Bean声明为一个切面,pointcut定义了一类切入点embark,expression含义是在任意返回类型、任意对象调用方法、任意入参的embrakOnQuest 方法都有效。

<aop:before>称为前置通知,<aop:after>称为后置通知。从这个示例中获得两个重要的观点:

  1. Minstrel仍然是一个POJO,没有任何代码表示它将被作为一个切面使用。
  2. Minstrel可以被应用到BraveKnight中,而BraveKnight不需要显示地调用。实际上,BraveKnight完全不知道Minstrel的存在。

Spring之旅(2)的更多相关文章

  1. 我的Spring之旅(二):为请求加入參数

    1.前言 在上一篇我的Spring之旅(一)中,我们仅仅是利用不带參数的请求返回一个网页或一段json,在实际的B/S.C/S网络交互中,请求中须要自己定义的參数.本篇将简单地为之前的请求加入參数. ...

  2. Spring之旅第六篇-事务管理

    一.什么是事务 什么是事务(Transaction)?事务是数据库中的概念,是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 有个非常经典的转账问题:A向B转款1000元,A转出成 ...

  3. Spring之旅

    Java使得以模块化构建复杂应用系统成为可能,它为Applet而来,但为组件化而留. Spring是一个开源的框架,最早由Rod Johnson创建.Spring是为了解决企业级应用开发的复杂性而创建 ...

  4. Spring学习笔记—Spring之旅

    1.Spring简介     Spring是一个开源框架,最早由Rod Johnson创建,并在<Expert One-on-One:J2EE Design and Development> ...

  5. SpringInAction读书笔记--第1章Spring之旅

    1.简化Java开发 Spring是一个开源框架,它的根本使命在于简化java开发.为了降低java开发的复杂性,Spring采取了以下4种关键策略: 基于POJO的轻量级和最小侵入性编程      ...

  6. Spring之旅第五篇-AOP详解

    一.什么是AOP? Aspect oritention programming(面向切面编程),AOP是一种思想,高度概括的话是“横向重复,纵向抽取”,如何理解呢?举个例子:访问页面时需要权限认证,如 ...

  7. Spring之旅第四篇-注解配置详解

    一.引言 最近因为找工作,导致很长时间没有更新,找工作的时候你会明白浪费的时间后面都是要还的,现在的每一点努力,将来也会给你回报的,但行好事,莫问前程!努力总不会有错的. 上一篇Spring的配置博客 ...

  8. Spring之旅第三篇-Spring配置详解

    上一篇学习了IOC的概念并初步分析了实现原理,这篇主要学习Spring的配置,话不多说,让我们开始! 一.Bean元素配置 1.1 基本配置 看一个最基本的bean配置 <bean name=& ...

  9. Spring之旅第二篇-Spring IOC概念及原理分析

    一.IOC概念 上一篇已经了解了spring的相关概念,并且创建了一个Spring项目.spring中有最重要的两个概念:IOC和AOP,我们先从IOC入手. IOC全称Inversion of Co ...

随机推荐

  1. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  2. 重撸js_2_基础dom操作

    1.node 方法 返回 含义 nodeName String 获取节点名称 nodeType Number 获取节点类型 nodeValue String 节点的值(注意:文本也是节点) 2.inn ...

  3. CodeSimth - .Net Framework Data Provider 可能没有安装。解决方法

    今天想使用CodeSimth生成一个sqlite数据库的模板.当添加添加数据库的时候发现: .Net Framework Data Provider 可能没有安装. 下面找到官方的文档说明: SQLi ...

  4. EditText 基本用法

    title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...

  5. iOS审核这些坑,腾讯游戏也踩过

    作者:Jamie,专项技术测试工程师,在iOS预审和ASO优化领域从事专项测试相关工作,为腾讯游戏近100个产品提供专项服务. WeTest 导读 在App上架苹果应用商店的过程中,相信大多数iOS开 ...

  6. [C#] 简单的 Helper 封装 -- RandomHelper

    using System; namespace Wen.Helpers { /// <summary> /// 随机数助手 /// </summary> public seal ...

  7. thinkphp数据的查询和截取

    public function NewsList(){ $this->assign('title','news'); $p = I('page',1); $listRows = 6; $News ...

  8. 文档对象模型DOM通俗讲解

    转自:http://www.jb51.net/article/42671.htm 在开始之前先说一点,DOM是非常容易理解的,但是大家说的太官方,让人很是难于理解,我们就用非常简单的语言翻译一遍.加深 ...

  9. java观察者模式

      像activeMQ等消息队列中,我们经常会使用发布订阅模式,但是你有没有想过,客户端时如何及时得到订阅的主题的信息?其实就里就用到了观察者模式.在软件系统中,当一个对象的行为依赖于另一个对象的状态 ...

  10. java.IO输入输出流:过滤流:buffer流和data流

    java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...