异常增强

/ Spring / 没有评论 / 303浏览

异常增强的功能顾名思义就是在抛出异常的时候添加横切的逻辑。最典型的引用就是事物管理。本篇还将以用户注册为例,演示异常增强的使用。

public class UserServiceException implements ThrowsAdvice {
public void afterThrowing(Method method,Object [] objects,Object target,Exception exception) throws Throwable {
System.out.println("异常增强");
System.out.println(String.format("用户注册回滚: username: %s nickName: %s password: %s", objects[0], objects[1], objects[2]));
}
}
public class UserServiceImpl implements IUserService {

public void login(String username, String password) {
System.out.println(String.format("用户登陆: username: %s password: %s", username, password));
}

public void register(String username, String nickName, String password) {
System.out.println(String.format("用户注册: username: %s nickName: %s password: %s", username, nickName, password));
System.out.println(10 / 0); // 抛出运行时异常
}

}
<bean id="userServiceException" class="com.jilinwula.spring.aop.UserServiceException"/>
<bean id="target" class="com.jilinwula.spring.aop.UserServiceImpl"/>
<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.jilinwula.spring.aop.IUserService"
p:interceptorNames="userServiceException"
p:target-ref="target"/>
@Test
public void test() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
IUserService userService = applicationContext.getBean("userService", IUserService.class);
userService.register("admin","吉林乌拉","jilinwula");
}
用户注册: username: admin nickName: 吉林乌拉 password: jilinwula
异常增强
用户注册回滚: username: admin nickName: 吉林乌拉 password: jilinwula

java.lang.ArithmeticException: / by zero

at com.jilinwula.spring.aop.UserServiceImpl.register(UserServiceImpl.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:125)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy6.register(Unknown Source)
at com.jilinwula.spring.IOCTest.test(IOCTest.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)<br></code></pre><p>如果我们将UserServiceImpl中的异常代码去掉后,则不会执行UserServiceException代码中的增强。</p><pre><code><span style="color:#000000;">public class </span><span style="color:#336699;">UserServiceImpl </span><span style="color:#000000;">implements </span><span style="color:#336699;">IUserService </span><span style="color:#000000;">{<br></span><span style="color:#000000;"><br></span><span style="color:#000000;">  public void login(</span><span style="color:#336699;">String username</span><span style="color:#000000;">, </span><span style="color:#336699;">String password</span><span style="color:#000000;">) {<br></span><span style="color:#000000;">    </span><span style="color:#336699;">System</span><span style="color:#000000;">.</span><span style="color:#660e7a;font-weight:bold;font-style:italic;">out</span><span style="color:#000000;">.println(</span><span style="color:#336699;">String</span><span style="color:#000000;">.</span><span style="color:#777777;">format</span><span style="color:#000000;">(</span><span style="color:#d25252;">"</span><span style="color:#d25252;font-family:'Menlo';">用户登陆</span><span style="color:#d25252;">: username: %s password: %s"</span><span style="color:#000000;">, </span><span style="color:#336699;">username</span><span style="color:#000000;">, </span><span style="color:#336699;">password</span><span style="color:#000000;">));<br></span><span style="color:#000000;">  }<br></span><span style="color:#000000;"><br></span><span style="color:#000000;">  public void register(</span><span style="color:#336699;">String username</span><span style="color:#000000;">, </span><span style="color:#336699;">String nickName</span><span style="color:#000000;">, </span><span style="color:#336699;">String password</span><span style="color:#000000;">) {<br></span><span style="color:#000000;">    </span><span style="color:#336699;">System</span><span style="color:#000000;">.</span><span style="color:#660e7a;font-weight:bold;font-style:italic;">out</span><span style="color:#000000;">.println(</span><span style="color:#336699;">String</span><span style="color:#000000;">.</span><span style="color:#777777;">format</span><span style="color:#000000;">(</span><span style="color:#d25252;">"</span><span style="color:#d25252;font-family:'Menlo';">用户注册</span><span style="color:#d25252;">: username: %s nickName: %s password: %s"</span><span style="color:#000000;">, </span><span style="color:#336699;">username</span><span style="color:#000000;">, </span><span style="color:#336699;">nickName</span><span style="color:#000000;">, </span><span style="color:#336699;">password</span><span style="color:#000000;">));<br></span><span style="color:#000000;">  }<br></span><span style="color:#000000;"><br></span><span style="color:#000000;">}</span></code></pre><pre><code>用户注册: username: admin nickName: 吉林乌拉 password: jilinwula<br></code></pre>