Spring AOP(4)- 异常增强

实现原理:

异常增强完成功能:在目标类的抛出异之前嵌入增强逻辑.
实现原理:
1. 实现接口 ThrowsAdvice,重写函数 afterThrowing ,在目标方法抛出异常之前嵌入逻辑代码,常用于事务处理的回滚
2. 利用ProxyFactoryBean代理类调用目标类方法
3.配置Spring XML

定义接口类

package com.advice;

import com.smart.domain.User;

import java.sql.SQLException;

/**
 * @author Duoduo
 * @version 1.0
 * @date 2017/4/22 18:58
 */
public interface IUserDao {
    int addUser(User user);
    int updateUser(User user);
    void deleteUser(User user);
    void removeUser(User user) throws SQLException;
}

接口实现类

package com.advice;

import com.smart.domain.User;

import java.sql.SQLException;

/**
 * @author Duoduo
 * @version 1.0
 * @date 2017/4/22 19:00
 */
public class UserDaoImpl implements IUserDao {
    @Override
    public int addUser(User user) {
        System.out.println("Add user");
        return 0;
    }

    @Override
    public int updateUser(User user) {
        System.out.println("Update user");
        return 0;
    }

    @Override
    public void deleteUser(User user) {
        throw new RuntimeException("exception test");
    }

    @Override
    public void removeUser(User user) throws SQLException {
        throw new SQLException("SQLException Test");
    }
}

定义异常增强类

package com.advice;

import org.springframework.aop.ThrowsAdvice;

import java.lang.reflect.Method;

/**
 * 异常抛出增强:当抛出异常之前执行,常用于事务处理的回滚
 * @author Duoduo
 * @version 1.0
 * @date 2017/4/23 10:34
 */
public class TransactionManagerAdvice implements ThrowsAdvice {

    public void afterThrowing(Method method, Object[] args, Object target, Exception ex){
        System.out.println("*******************");
        System.out.println("method name : "+ method.getName());
        System.out.println("after throw exception :"+ ex.getMessage() );
        System.out.println("rollback ... ");
    }

}

Spring XML 配置

特别注意:代理工厂是 ProxyFactoryBean 不是 ProxyFactory

<!-- 代理设置 -->
<bean id="userDaoImpl" class="com.advice.UserDaoImpl"/>
<bean id="transactionManagerAdvice" class="com.advice.TransactionManagerAdvice"/>

<bean id="addUserProxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean"
      p:proxyInterfaces="com.advice.IUserDao"
      p:target-ref="userDaoImpl"
      p:interceptorNames="transactionManagerAdvice"/>

两种调用方式:
1.根据XML配置来进行调用测试
2.自己创建代理来进行测试

另种方法都需要注意:此处代理获取的是代理Bean,指向的是Interface的代理。

@Test
public  void deleteUserTest(){
    System.out.println("************ deleteUserTest ************");

    IUserDao userDao = new UserDaoImpl();
    ThrowsAdvice throwsAdvice = new TransactionManagerAdvice();

    //创建代理工厂
    ProxyFactory proxyFactory = new ProxyFactory();
    //设置代理目标类
    proxyFactory.setTarget(userDao);

    //为代理添加增强
    proxyFactory.addAdvice(throwsAdvice);
    //生成代理实例
    IUserDao proxyUserDao = (IUserDao)proxyFactory.getProxy();


    try {
        proxyUserDao.removeUser(user);
    } catch (SQLException e) {
        e.printStackTrace();
    }

    proxyUserDao.deleteUser(user);
}

测试结果

************ deleteUserTest *******************************
method name : removeUser
after throw exception :SQLException Test
rollback ... 
java.sql.SQLException: SQLException Test
    at com.advice.UserDaoImpl.removeUser(UserDaoImpl.java:32)
    at com.advice.UserDaoImpl$$FastClassBySpringCGLIB$$5dedbffe.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
    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.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
    at com.advice.UserDaoImpl$$EnhancerBySpringCGLIB$$348998ab.removeUser(<generated>)
    at com.advice.UserDaoAdviceTest.deleteUserTest(UserDaoAdviceTest.java:123)
    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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    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)
        *******************
        method name : deleteUser
        after throw exception :exception test
        rollback ... 
        四月 23, 2017 4:16:31 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
        信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@670002: startup date [Sun Apr 23 16:16:31 CST 2017]; root of context hierarchy
        四月 23, 2017 4:16:31 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
        信息: Loading XML bean definitions from class path resource [spring-another-context.xml]

        java.lang.RuntimeException: exception test

    at com.advice.UserDaoImpl.deleteUser(UserDaoImpl.java:27)
    at com.advice.UserDaoImpl$$FastClassBySpringCGLIB$$5dedbffe.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
    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.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
    at com.advice.UserDaoImpl$$EnhancerBySpringCGLIB$$348998ab.deleteUser(<generated>)
    at com.advice.UserDaoAdviceTest.deleteUserTest(UserDaoAdviceTest.java:128)
    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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值