Spring 实战 第四版 P11-P16 aop入门

1.1.3 应用切面

DI能够让相互协作的软件组件保持松散耦合,面向切面编程(AOP)允许你把遍布应用各处的功能分离出来形成可重用的组件。

除了实现自身核心的功能之外,这些组件还经常承担着额外的职责。诸如日志、事务管理和安全这样的系统服务经常融入到自身具有核心业务逻辑的组件中去,这些系统服务通常被称为横切关注点,因为它们会跨越系统的多个组件。

1. 这些横切关注点的问题,如果你想要改变比如(日志,或者安全如何实现)。如果他们被嵌在其他代码中,会非常麻烦,你需要重复改。

2. 即使你全部把关注点抽出来,你还是需要有很多不同的地方调用他们!!!(重复代码)

3. 代码的逻辑看起来很混乱。(一个向地址簿增加地址条目的 方法应该只关注如何添加地址,而不应该关注它是不是安全的或者是否需要支持事务。)

例子:切面想象成覆盖在很过组件上面的一个外壳,应用是那些实现鸽子业务功能的模块组成的。借助AOP我们可以使用各种功能层去包裹核心业务层。这些功能层以声明的方式灵活的应用到系统当中!!!

你的核心应用甚至根本不知道它们的存在。这是一个非常 强大的理念,可以将安全、事务和日志关注点与核心业务逻辑相分离

 

个人理解:我觉得AOP就是把一些重复的,通用的代码(例如日志,安全,事务)等独立抽出来,成为一个独立的模块,利用Spring的AOP通过配置的方式织入需要的业务模块中(学生服务等)。通过AOP,我们的业务代码不需要知道这些事务,安全是怎么做的,可以关注于业务代码之上。有利于关注点分离!!!

代码:

代码例子,还是使用之前的骑士的例子,我们需要一个诗人来记录骑士的事迹。

public class Minstrel {

    private PrintStream stream;

    public Minstrel(PrintStream stream) {
        this.stream = stream;
    }

    public void singBeforeQuest() {
        stream.println("Fa la la, the knight is so brave");
    }

    public void singAfterQuest() {
        stream.println("Tee hee hee, the brace knight did embark on a quest!");
    }
}

我们配置了一个诗人,来记录骑士,并且我们把诗人作为依赖,注入了骑士!

public class BraveKnight implements Knight {

    private Quest quest;
    private Minstrel minstrel;

    public BraveKnight(Quest quest, Minstrel minstrel) {
        this.quest = quest;
        this.minstrel = minstrel;
    }

    public void embarkOnQuest(){
        minstrel.singBeforeQuest(); //调用诗人记录,出征前
        quest.embark();
        minstrel.singAfterQuest(); //出征后
    }
}

Fa la la, the knight is so brave
embark on the quest to slay the dragon
Tee hee hee, the brace knight did embark on a quest!

虽然代码是符合预期的,但是,有些东西好像有点不太对!!

管理他的吟游诗人真的是骑士职责范围内的工作吗?在我看 来,吟游诗人应该做他份内的事,根本不需要骑士命令他这么做。毕竟,用诗歌记载骑士的

探险事迹,这是吟游诗人的职责。为什么骑士还需要提醒吟游诗人去做他份内的事情呢?

此外,因为骑士需要知道吟游诗人,所以就必须把吟游诗人注入到BarveKnight类中。这 不仅使BraveKnight的代码复杂化了,而且还让我疑惑是否还需要一个不需要吟游诗人的 骑士呢?如果Minstrel为null会发生什么呢?我是否应该引入一个空值校验逻辑来覆盖 该场景?

简单的BraveKnight类开始变得复杂,如果你还需要应对没有吟游诗人时的场景,那代码 会变得更复杂。但利用AOP,你可以声明吟游诗人必须歌颂骑士的探险事迹,而骑士本身并 不用直接访问Minstrel的方法。

个人理解:记录这个工作与骑士无关,并不是他的业务范围!!骑士不需要知道诗人,只需要管自己的事情!!诗人就是用来记录的,我们需要将记录这个关注点从骑士这个类中分离出去。

使用AOP例子:

 <bean id="minstrel" class="com.springinaction.knights.Minstrel">
        <constructor-arg value="#{T(System).out}"/>
    </bean>
    <aop:config> <!--aop定义 -->
        <aop:aspect ref="minstrel"> <!-- 切面 -->
            <aop:pointcut id="embark" expression="execution(* *.embarkOnQuest(..))"/>
            <aop:before method="singBeforeQuest" pointcut-ref="embark"/>
            <aop:after method="singAfterQuest" pointcut-ref="embark"/>
        </aop:aspect>
    </aop:config>

ps:需要在maven中添加几个依赖

<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.3.7.RELEASE</version>
        </dependency>

个人理解:我们不需要添加任何东西在我们的knight类中,只需要在xml中配置一个切面,把ministrel配置成为一个bean,然后声明为一个切面。切入点为执行embarkOnQuest()的时候,配置了前置,和后置通知。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值