DI(Dependency Inversion):依赖反转,在进行模块设计的时候,高层抽象模块通常是与业务逻辑(底层模块)相关的模块,高层模块应该具有可复用的。在设计上模块应该依赖于模块的抽象,而不是底层模块的具体实现,即“程序不应依赖实现,而是依赖于抽象接口”。
从具体应用可以看出,在这种设计模式下,高层模块的实现不需要更改即可实现读取不同磁盘内容的功能,这里也体现了Java多态的思想。
如果高层模块直接依赖底层实现,即高层模块中代码为:private DiskReadImp read = new DiskReadImp ();那么当需要读取SD卡内容的时候应修改为:private SDReadImp read = new SDReadImp ();则使得高层模块依赖于底层模块的实现。
IOC(Inversion of Control)控制反转/依赖注入,在spring中,它是DI的一种实现,指程序在运行过程中,如果需要调用另一个对象协助时,无需在代码中创建该对象,而是通过依赖外部注入的方式实现。Spring中IOC体现在对象的创建通过Bean管理来实现。
AOP(Aspect Oriented Programming)面向切面编程,AOP思想为,当需要对程序中某一功能(方法)进行增加时,不需要修改原来的程序(修改源码可称为纵向增强),而采用横切的方式来实现功能的完善。
public class Login {
public String login (){
//登录逻辑,现需要添加日志功能
}
}
纵向增强:
public class Login {
public String login (){
//日志逻辑代码
//登录逻辑,即修改源代码
}
}
横切实现:
在Struts2中,AOP思想的实现通过拦截器Inteceptor,在spring中体现在前置通知、后置通知、环绕通知、异常通知和引入通知。
Struts2中自定义拦截器
1、方法前拦截(前置通知)
public class LoginInterceptor extends AbstractInterceptor {
public String intercept (ActionInvacation ai) throws Exception{
…
return ai.invoke();
}
}
2、拦截结果监听器(后置通知)
public class MyResultListener implements PreResultListener {
public void beforeResult (ActionInvacation ai,String Result) throws Exception{
…
}
}
拦截器配置:
<interceptors>
<interceptor name=”beforeMethod” class=”learn. interceptor . LoginInterceptor”
/interceptor>
<interceptor name=”beforeResult” class=”learn. interceptor .MyResultListener”
/interceptor>
</interceptors>
<action name=”login” class=”learn.action.LoginAction”>
<result name=”success”>/success.jsp</result>
<interceptor-ref name=”defaultStack”/> //配置默认拦截器栈
<interceptor-ref name=” beforeMethod”/> //方法前拦截
<interceptor-ref name=” beforeResult”/> //结果监听器
</action>
在Struts2拦截器中,可以对特定的方法进行拦截,称为拦截器方法过滤。
public class MethodInterceptor extends MethodFilterInterceptor {
public String doIntercept (ActionInvacation ai) throws Exception{
…
return ai.invoke();
}
}
<interceptors>
<interceptor name=”methodFilter” class=”learn. interceptor . MethodInterceptor”
/interceptor>
</interceptors>
<action name=”login” class=”learn.action.LoginAction”>
<result name=”success”>/success.jsp</result>
<interceptor-ref name=”defaultStack”/> //配置默认拦截器栈
<interceptor-ref name=” methodFilter”> //方法前拦截
<param name=”excludeMethods”>指定Action中不需要过滤的方法</param>
<param name=”excludeMethods”>指定Action中需要过滤的方法</param>
</interceptor-ref>
</action>
Spring 中AOP的配置
连接点(Joinpoint):应用程序可以增强的方法。
切面(Aspect):应用程序需要增强的功能。
通知(Advice):切面的实际实现。
切入点(pointcut):把通知应用到切面的过程。
目标对象(Target Object):被增强的对象(类)。
Spring中增强的实际实现是通过代理实现的,代理是指和目标对象具有相同功能的类。
Spring 中AOP的配置方式一:
<!-- 定义目标对象 -->
<bean name="productDao" class="com.springAop.dao.daoimp.ProductDaoImpl" />
<!-- 定义切面 -->
<bean name="myAspectXML" class="com.springAop.AspectJ.MyAspectXML" />
<!-- 配置AOP 切面 -->
<aop:config>
<!-- 定义切点函数 -->
<aop:pointcut id="pointcut" expression="execution(*com.springAop.dao.ProductDao.add(..))" />
<!-- 定义其他切点函数 -->
<aop:pointcut id="delPointcut" expression="execution(* com.springAop.dao.ProductDao.delete(..))" />
<!-- 定义通知 order 定义优先级,值越小优先级越大-->
<aop:aspect ref="myAspectXML" order="0">
<!-- 定义通知
method 指定通知方法名,必须与MyAspectXML中的相同
pointcut 指定切点函数
-->
<aop:before method="before" pointcut-ref="pointcut" />
<!-- 后置通知 returning="returnVal" 定义返回值 必须与类中声明的名称一样-->
<aop:after-returning method="afterReturn" pointcut-ref="pointcut" returning="returnVal" />
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut" />
<!--异常通知 throwing="throwable" 指定异常通知错误信息变量,必须与类中声明的名称一样-->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="throwable"/>
<!--
method : 通知的方法(最终通知)
pointcut-ref : 通知应用到的切点方法
-->
<aop:after method="after" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
Spring 中AOP的配置方式二:
<beans>
<bean id="hostess" class="human.Hostess" scope="prototype">
<property name="dog" ref="dog1"></property>
</bean>
<bean id="dog1" class="dog.Taidi" scope="prototype"></bean>
<bean id="dog2" class="dog.Labuladuo" scope="prototype"></bean>
<bean id="humanHandler" class="aop.HumanHandler">
<property name="target" ref="hostess"></property>
</bean>
<bean id="humanProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="handlerName" ref="humanHandler"></property>
<property name="target" ref="hostess"></property>
</bean>
</beans>