SpringAOP面向切面编程
spring中三大核心思想之一aop(面向切面编程):
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <!-- 定义bean --> <bean id="stuservice" class="com.lxit.aop.service.studentservice" /> <!-- aop配置 --> <!-- 添加aspect的bean --> <bean id="logaspect" class="com.lxit.aop.aspect.logaspect" /> <aop:config> <!-- 定义一个pointcut --> <aop:pointcut id="servicepointcut" expression="execution(* com.lxit.aop.service.*.*(..))" /> <!-- 定义aspect,引用生成的aspectbean 并指定pointcut 和 method--> <aop:aspect id="aspect1" ref="logaspect"> <aop:after pointcut-ref="servicepointcut" method="logadd" /> </aop:aspect> </aop:config> </beans>
public static void main(string[] args) { applicationcontext ac = new classpathxmlapplicationcontext("spring.xml"); studentservice service = (studentservice) ac.getbean("stuservice"); service.add(); service.getstudent(); }
异常抛出增强:
异常抛出增强的特点是在目标方法抛出异常时织入增强处理,
但是异常处理一般会需要获取异常参数。
在配置文件中添加异常处理的aspect。
使用<aop:after-throwing来进行异常织入。
public class exceptionaspect { public void exceptionlog(exception e){ system.out.println("发生异常,写入日志。" + e.getmessage()); } }
<bean id="exceptionaspect" class="com.lxit.aop.aspect.exceptionaspect" /> <aop:config> <!-- 定义一个pointcut --> <aop:pointcut id="servicepointcut" expression="execution(* com.lxit.aop.service.*.*(..))" /> <!-- 定义aspect,引用生成的aspectbean 并指定pointcut 和 method--> <aop:aspect id="aspect2" ref="exceptionaspect"> <!-- 表示当程序发生异常后才织入 --> <aop:after-throwing method="exceptionlog" pointcut-ref="servicepointcut" throwing="e"/> </aop:aspect> </aop:config>
环绕增强:
环绕增强在目标方法的前后都可以织入增强处理
环绕增强是功能最强大的增强处理,spring把目标方法的控制权全部交给了它
在环绕增强处理中,可以获取或修改目标方法的参数、返回值,可以对它进行异常处理,甚至可以决定目标方法是否执行
public class aroundlogger { public object aroundlogger(proceedingjoinpoint jp) throws throwable { … } }
<bean id="thelogger" class="aop. aroundlogger"></bean> <aop:config> <aop:pointcut id="pointcut" expression="execution(* biz.iuserbiz.*(..))" /> <aop:aspect ref="thelogger"> <aop:around method="aroundlogger" pointcut-ref="pointcut" /> </aop:aspect> </aop:config>
五中织入方式的区别:
<aop:before …>:在目标方法调用之前织入。
只要before方法执行完成,目标方法总会被调用,但before可以通过抛出异常来阻止目标方法执行,before不能访问目标方法的返回值。
<aop:after…>:在目标方法调用之后织入。
after不能组织目标方法的执行,after不能访问目标方法的返回值。
<aop:after-throwing..>:抛出异常时织入。如果指定throwing必须指定一个异常参数,增强方法中必须和此参数同名,类型必须大于该异常类型。
<aop:after-returning…>:在目标方法成功执行之后织入。
after-returning:不能阻止目标方法的执行,可以访问目标方法的返回值,但不能修改。
<aop:around…>:在目标方法调用之前和调用之后织入。它的处理方法必须包含一个proceedingjoinpoint形参。
aop:around:可以组织目标方法的执行,可以访问目标方法的返回值,可以修改返回值。
以上增强器都可以指定args来指定参数
在struts2,hibernate,spring整合中就可以看到一种很好的效果。
在serivce层定义成一个切点在执行操作前可以开启一系列操作,比如写入日志,事务等操作是一种典型的案例。
aop使用场景
aop用来封装横切关注点,具体可以在下面的场景中使用:
authentication 权限 caching 缓存 context passing 内容传递 error handling 错误处理 lazy loading 懒加载
debugging 调试 logging, tracing, profiling and monitoring 记录跟踪 优化 校准 performance optimization 性能优化
persistence 持久化 resource pooling 资源池 synchronization 同步 transactions 事务