Spring AOP(面向切面编程)
来源:互联网 发布:北塔软件联系人 编辑:程序博客网 时间:2024/05/01 21:02
在日常生活中,会遇到各种各样的中介机构,比如猎头公司,律师事务所,婚姻介绍所,房产公司等。在这些单位工作的人员均可称为代理人。代理人的共同特征是可以代替委托人去和第三方通信。譬如:律师代替委托人打官司,猎头代替委托人物色人才,红娘代替委托人寻找对象,房产代理人代替委托人出租房屋。
代理人可以在第三方和委托人之间转发或过滤消息,但是不能取代委托人的任务。譬如你要找女朋友,委托你一要好的哥们去帮你物色,结果被他给物色了。这就不叫代理。
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
1、前置通知:在目标方法执行之前调用。
实现MethodBeforeAdvice接口,接口方法如下:
void before(Method method,Object[] args,Object target) throws Throwable;
这个接口为我们提供了获得目标方法,参数,目标对象的机会。注意:我们没必要在这个方法里面调用目标方法(可以通过反射调用),因为,这个接口方法结束后目标方法将调用,这才叫前置嘛(在目标方法之前)。要想终止程序的继续运行,只有抛异常或调用System.exit()
2、 后置通知:在目标方法执行之后调用。
实现AfterReturningAdvice接口,该接口方法如下:
void afterReturning(Object returnValue,Method method,
Object[] args, Object target) throws Throwable
这个方法多了一个目标方法的返回值参数。同理要结束程序流程只有抛异常和调用System.exit()方法。
3、环绕通知:拦截目标方法的执行,可在该类型通知里自行调用目标方法。
实现MethodInterceptor接口,该接口在aopalliance.jar包里,这个包是aop联盟(aop编程接口,为实现aop编程接口重用)的包,可以理解成aop编程规范接口。
接口方法如下:
Object invoke(MethodInvocation invocation) throws Throwable;
环绕通知和上述2个通知的区别:
1)由于环绕通知是拦截目标方法的执行,所以在这个方法里用户可以通过invocation.proceed()方法调用目标方法,这点和MethodBeforeAdvice不同,它的目标方法总是会执行,除非抛异常或执行System.exit()方法。
2)正常情况下这个方法返回的就是目标方法(invocation.proceed()返回的结果)的返回值,但可以在这个接口方法里改变目标方法的返回值,除非必须如此,否则最好不要这样使用。这个接口与AOP联盟的AOP框架兼容。
因为要显示的调用目标方法(invocation.proceed()),所以更推荐使用上述2种方式。
4、异常通知:当目标方法抛出异常时调用。
实现ThrowsAdvice接口,该接口是标记接口,没有定义任何一个必须实现的方法,但实现该接口的类必须至少有一个如下形式的方法:
package com.spring.aop;/** * 切面 * */public class TestAspect { public void doAfter(JoinPoint jp) { System.out.println("log Ending method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } public Object doAround(ProceedingJoinPoint pjp) throws Throwable { long time = System.currentTimeMillis(); Object retVal = pjp.proceed(); time = System.currentTimeMillis() - time; System.out.println("process time: " + time + " ms"); return retVal; } public void doBefore(JoinPoint jp) { System.out.println("log Begining method: " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName()); } public void doThrowing(JoinPoint jp, Throwable ex) { System.out.println("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception"); System.out.println(ex.getMessage()); } private void sendEx(String ex) { //TODO 发送短信或邮件提醒 }}
package com.spring.service;/** * 接口A */public interface AService { public void fooA(String _msg); public void barA();}
package com.spring.service;/** *接口A的实现类 */public class AServiceImpl implements AService { public void barA() { System.out.println("AServiceImpl.barA()"); } public void fooA(String _msg) { System.out.println("AServiceImpl.fooA(msg:"+_msg+")"); }}
package com.spring.service;/** * Service类B */public class BServiceImpl { public void barB(String _msg, int _type) { System.out.println("BServiceImpl.barB(msg:"+_msg+" type:"+_type+")"); if(_type == 1) throw new IllegalArgumentException("测试异常"); } public void fooB() { System.out.println("BServiceImpl.fooB()"); }}
ApplicationContext.xml
<?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-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" default-autowire="autodetect"> <aop:config> <aop:aspect id="TestAspect" ref="aspectBean"> <!--配置com.spring.service包下所有类或接口的所有方法--> <aop:pointcut id="businessService" expression="execution(* com.spring.service.*.*(..))" /> <aop:before pointcut-ref="businessService" method="doBefore"/> <aop:after pointcut-ref="businessService" method="doAfter"/> <aop:around pointcut-ref="businessService" method="doAround"/> <aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex"/> </aop:aspect> </aop:config> <bean id="aspectBean" class="com.spring.aop.TestAspect" /> <bean id="aService" class="com.spring.service.AServiceImpl"></bean> <bean id="bService" class="com.spring.service.BServiceImpl"></bean></beans>
测试类AOPTest
public class AOPTest extends AbstractDependencyInjectionSpringContextTests {private AService aService;private BServiceImpl bService;protected String[] getConfigLocations() {String[] configs = new String[] { "/applicationContext.xml"};return configs;}/** * 测试正常调用 */public void testCall(){System.out.println("SpringTest JUnit test");aService.fooA("JUnit test fooA");aService.barA();bService.fooB();bService.barB("JUnit test barB",0);}/** * 测试After-Throwing */public void testThrow(){try {bService.barB("JUnit call barB",1);} catch (IllegalArgumentException e) {}}public void setAService(AService service) {aService = service;}public void setBService(BServiceImpl service) {bService = service;}}
运行结果如下:
log Begining method: com.spring.service.AServiceImpl.fooAAServiceImpl.fooA(msg:JUnit test fooA)log Ending method: com.spring.service.AServiceImpl.fooAprocess time: 0 mslog Begining method: com.spring.service.AServiceImpl.barAAServiceImpl.barA()log Ending method: com.spring.service.AServiceImpl.barAprocess time: 0 mslog Begining method: com.spring.service.BServiceImpl.fooBBServiceImpl.fooB()log Ending method: com.spring.service.BServiceImpl.fooBprocess time: 0 mslog Begining method: com.spring.service.BServiceImpl.barBBServiceImpl.barB(msg:JUnit test barB type:0)log Ending method: com.spring.service.BServiceImpl.barBprocess time: 0 mslog Begining method: com.spring.service.BServiceImpl.barBBServiceImpl.barB(msg:JUnit call barB type:1)log Ending method: com.spring.service.BServiceImpl.barBmethod com.spring.service.BServiceImpl.barB throw exception测试异常讲解:
我们先看配置文件中 有:before after around throw
log Begining method: com.spring.service.AServiceImpl.fooAAServiceImpl.fooA(msg:JUnit test fooA)log Ending method: com.spring.service.AServiceImpl.fooAprocess time: 0 ms至于为什么会没有throw因为在fooA执行过程中并没有抛出异常。
- spring面向切面编程(aop)
- Spring AOP 面向切面编程
- Spring AOP 面向切面编程
- Spring面向切面编程AOP
- Spring AOP(面向切面编程)
- Spring AOP面向切面编程
- Spring 面向切面编程AOP
- Spring面向切面编程AOP
- Spring AOP面向切面编程
- Spring AOP面向切面编程
- spring aop面向切面编程
- Spring AOP面向切面编程
- Spring AOP:面向切面编程
- Spring 面向切面编程AOP
- Spring面向切面编程(AOP)
- Spring---AOP面向切面编程
- Spring面向切面编程AOP
- Spring:Aop面向切面编程
- java.lang.OutOfMemoryError: PermGen space及其解决方法
- 计算机视觉资源汇总 - Part V(计算机视觉代码合集一)
- Linux之V4L2基础编程
- cocos2dx3.X项目重写(五)添加分数,开始和结束场景。
- ajax页面使用pushState方法做SEO
- Spring AOP(面向切面编程)
- C++大数运算之加法,减法
- SQL Server 日期的加减函数: DATEDIFF DATEADD
- Java动态绑定机制的内幕
- java基础汇总(一)
- 计算机视觉资源汇总 - Part VI(计算机视觉代码合集二)
- 推荐个应用网站
- Android设置透明、半透明等效果
- 荷兰国旗