依赖注入DI
Spring通过应用上下文Application Context装载bean的定义并把他们组装起来
例如:knight.xml中的bean是通过XML来进行配置,可以选择*ClassPathXMLApplicationContext*作为应用上下文
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/knight.xml");
Knight knight = context.getBean(Knight.class);
knight.embarkOnQuest();
context.close();
上述过程中,通过knight完成embarkOnQuest方法,但该类完全不知道knight这个bean对象具体对应的类是哪个,也不知道embarkOnQuest方法具体执行了什么。从而实现了程序的松耦合,该方式即依赖注入DI。
AOP:面向切面编程,可理解为覆盖在多个组件上的外壳,与核心业务无关的通用服务以声明的方式灵活地应用到系统中,核心应用甚至感觉不到它的存在。
优点:提高了核心代码的内聚,符合面向对面编程的思想
如创建一个吟游诗人类来记录骑士相关探险故事
public class Minsterl(){
private PrintStream stream;
punlic Minsterl(){
this.stream = stream;
}
public void singBeforeQuest(){
stream.println("骑士开始冒险");
}
public void singAfterQuest(){
stream.println("骑士冒险结束");
}
}
可以看到 吟游诗人 Minster 只是一个简单的POJO类,如下两种方式实现骑士冒险前后进行传颂。
public class BraveKnight implents Knight(){
private Quest quest;
private Minsterl minsterl;
public BraveKnight(Quest quest,Minsterl minsterl){
this.quest = quest;
this.minsterl = minsterl;
}
public void embarkOnQuest(){
minsterl.singBeforeQuest();
quest.embark();
minsterl.singAfterQuest();
}
}
上面的代码实现了 在knight执行embarkOnQuest任务的前后吟游诗人minster记录了骑士冒险的前后,但knight的任务就是embarOnQuest,吟游诗人的记录动作是否需要其来管理呢,是不是执行任务前还有校验吟游诗人是否存在,这就使代码变得复杂化。而AOP就是专门用来解决这个问题的。
在kngiht.xml中加入如下配置:
<bean id="minstrel" class="xxxx.Minstrel">
<constructor-arg value="#(T(System).out)"/>
</bean>
<aop:config>
<aop:aspect ref="minstrel">
<aop:pointcut id="embark" expression="execution(* *.embarkOnQuest(...))"/>
<aop:before pointcut-ref="embark" method="singBeforeQuest"/>
<aop:after pointcut-after="embark" method="singAfterQust"/>
</aop:aspect>
</aop:config>
上诉配置首先将Minstrel 声明为一个bean对象minstrel,然后通过<aop:aspect ref=“minstrel”>将该bean对象定义为一个切面,切点位置<aop:pointcut id=“embark” expression=“execution(* *.embarkOnQuest(…))”/>为BraveKnight的embarkOnQuest方法,然后声明<aop:before pointcut-ref=“embark” mehtod=“singBeforeQuest”>在调用embarkOnQuest
方法之前执行singBeforeQuest方法,再由<aop:after pointcut-ref=“embark” mehtod=“singAfterQuest”>声明embarkOnQuest执行完毕后调用singAfterQuest方法。
可以看到,通过AOP,实现了核心业务逻辑与通用服务的分离,实现了降耦。