Spring 核心DI, AOP简介

来源:互联网 发布:20142015cba总决赛数据 编辑:程序博客网 时间:2024/06/05 19:40

1、DI 依赖注入 (这里主要是思想,模仿实例代码运行可能会有误)

    作用:更容易使代码变得更简单、更容易理解和更容易测试。

    实例:任何一个又实际意义的应用都是有两个或者更多的类组成,这些类相互协作来完成特定的业务逻辑,通常,每个对象负责管理与自己相互协作的对象的引用,这将会导致高度耦合和难以测试的代码。如下:

public class DamselRescuingKnight implements Knight{        private rescueDamselQuest quest;            public DamselresuingKnight(){                quest = new ResueDamselQuest();                }           public void embarkOnQuest() throws QuestException{                quest.embark();                }}

        如上代码,在构造器中new了一个对象的实例,这使得ResueDamselQuest和DamselRescuingKnight紧密耦合在一起,因此极大限制了这个骑士(Knight)的能力。(这里说限制了骑士的能力,意思是:这里使用new一个对象,不如引用这个对象的父类,这样在上面的业务中给这个父类注入一个ResueDamselQuest实例就可以了,如果其他地方还用到这个业务逻辑,就可以给这个父类注入一个其他子类对象,这样可以重用代码)。

上面的代码紧耦合,紧耦合的代码难以复用,难以理解。 但是一定的耦合也是必须的,完全没有耦合的代码什么也做不了。使用依赖注入DI能很好解决这个问题。

public class BraveKnight implements Knight{private Quest quest;public BraveKnight(Quest quest){this.quest = quest;}public void embarkOnQuest() throws QuestException{quest.embark();}}
上面就是依赖注入的方式之一:构造器注入
依赖注入优点:松耦合

要完成上面的注入必须要通过XML配置bean, 创建应用组件之间的协作的行为通常称为:装配。Spring有多种装配Bean的方式,采用XML配置是最常用的方式。下面创建一个Knight.xml文件。

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.ws.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="knight" class="com.springinaction.knights.BraveKnight"><constructor-arg ref="quest" /></bean><bean id="quest" class="com.springinaction.knighs.SlayDragonQuest" /></beans>
工作原理:Spring通过上下文(Application Context)装在Bean的定义并把他们组装起来。Spring应用上下文全权负责对象的创建和组装。Spring自带了几种应用上下文的实现,他们之间主要的区别仅仅是如何加载它们的配置。因为knights.xml中的Bean实在XML中声明的,所以选择ClassPathXmlApplicationContext作为拥有上下文是比较合适的。该类加载位于应用系统classpath下的一个或者多个xml文件,ClassPathXmlApplicationContext加载knights.xml,并获得Knight对象的引用
装在Bean,并且注入到业务类中,进行测试,如下:

import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class KnightMain {public static void main(String[] args){AppcationContext context = new ClassPathXmlApplicationContext("knights.xml");Knight knight = (Knight)context.getBean("knight");knight.embarkOnQuest();}}


2、AOP 应用切面

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

比如日志、事务管理、安全此类的系统服务经常融入到有自身核心业务的组件中去,这些系统服务通常被称为横切关注点,他们总是跨越系统的多个组件。

如下图:

                                                        

AOP可以使这些服务模块化,并以声明的方式将他们应用到他们需要影响的组件中去。结果是这些组件具有高内聚性以及更加关注自身业务,完全不需要了解可能设计的系统服务的复杂性,总之,AOP确保POJO保持简单。如下:

         

我们可以吧切面想象为覆盖在很多组件之上的一个外壳,应用是由哪些实现各自业务功能的模块组成。利用AOP,你可以使用各种功能层去包裹核心业务层,这些层以声明的方式灵活应用到你的系统中,甚至你的核心应用根本不知道他们的存在。这可以将案却,失事务和日志关注点与你的核心业务逻辑分离。

简单的实例:

public class People {public void eatBeforeWan(){System.out.println("玩之前,要先吃饭··<span style="font-family: KaiTi_GB2312;">·</span><span style="font-family: KaiTi_GB2312;">");</span>}public void watherAfterWan(){System.out.println("完之后,要喝水···");}}
上面People这个类有两个方法,在玩之前之后会分别调用这两个方法。吧这两个方法加入你的业务中,如下:

public void happy(){knight.eatBeforeWan();knight.wan();  //核心业务类knight.watherAfterWan();}
虽然上面的代码不太繁琐,但是可以看出,我不关心玩之前之后干什么,我只要业务是“玩”,在我做正事的时候,让我做一些其他无关的事情,这个总感觉不太好。这里通过使用AOP,就可以解决这些繁琐无用的代码,让我们只关注核心业务就可以了。

配置:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.ws.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><!-- DI 依赖注入配置 --><bean id="knight" class="com.springinaction.knights.BraveKnight"><constructor-arg ref="quest" /></bean><bean id="quest" class="com.springinaction.knighs.SlayDragonQuest" /><!-- AOP 有关配置 --><bean id="minstrel" class="com.springinaction.knights.Minstrel"/> <aop:config><aop:aspect ref="minstrel"><!-- 定义切面 --><aop:pointcut id = "embark" expression="execution(* *.embarkOnuest(..))"/><!-- 前置通知 --><aop:before pointcut-ref="embark" method="eatBeforeWan"/><!-- 后置通知 --><aop:after pointcut-ref="embark" method="watherAfterWan"/></aop:aspect></aop:config></beans>













1 0
原创粉丝点击