关于Spring与Struts2中IOC与AOP的理解
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>