自定义ioc/aop(二)

什么是AOP

aop:Aspect oriented Programming 面向切面编程,区别于我们熟知的oop面向对象,aop是对于oop的一种补充。oop是一种垂直的继承关系,子类继承父类,可以避免大多数的重复代码,但是有一些重复代码的问题,无法通过继承解决,比如说A类是父类,B、C是子类,A类已有的方法,B、C不需要重复去实现,但是如果A里的不同方法里面有重复代码,该如何解决呢?
比如:在A类中有aA和aB两个方法,aA中有一个System.currentTimeMillis()记录方法执行性能的代码,aB也有一个这样的代码,这显然不能通过继承解决,这个时候就要用到AOP了。
AOP就是为了解决这类问题而诞生的

实现原理

动态代理

自定义实现AOP

利用上一篇博客提到的转账demo基础上,通过aop框架实现事务控制

TransationManager 事务控制管理器

public class TransationManager {
    // ioc 反射注入set方法,实例化ConnectionUtils
    ConnectionUtils connectionUtils;
    public void setConnectionUtils(ConnectionUtils connectionUtils){
        this.connectionUtils=connectionUtils;
    }
    // 开启手动提交事务
    public void beginTransation() throws SQLException {
       connectionUtils.getCurrentConnection().setAutoCommit(false);
    }
    // 提交事务
    public void commitTransation() throws SQLException {
        connectionUtils.getCurrentConnection().commit();
    }
    // 回滚事务
    public void rollbackTransation() throws SQLException {
        connectionUtils.getCurrentConnection().rollback();
    }
}

ProxyFactory 动态代理工厂

动态代理的实现有两种一种是JDKproxy一种是CGLIB,此处以jdkproxy为例

public class ProxyFactory {
    TransationManager transationManager;
    public void setTransationManager(TransationManager transationManager){
    this.transationManager=transationManager;
    };
public  Object getJDKProxy(Object object){
    // 创建动态代理对象
    return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() {
        @Override
        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
            try{
                // 打印被代理的对象
                System.out.println(object.getClass());
                // 打印被代理对象的执行方法
                System.out.println(method.getName());
                // 答应被代理对象的方法参数
                for (int i = 0; i <objects.length; i++) {
                    System.out.println(objects[i].toString());
                }
                // 开启手动提交事务
                transationManager.beginTransation();
                // 执行方法
                Object invoke = method.invoke(object, objects);
                // 提交事务
                transationManager.commitTransation();
                return invoke;
            }catch (Exception e){
                // 回滚事务
                System.out.println("执行回滚");
                transationManager.rollbackTransation();
                return null;
            }
        }
    });
}
}

Beans.xml

在上一版ioc基础上,添加上我们新的bean

<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<!--动态代理-->
    <bean id="proxyFactory" class="utils.ProxyFactory">
        <property name="TransationManager" ref="transationManager"></property>
    </bean>
    
    <bean id="bankService" class="bank.service.impl.BankServiceImpl">
        <property name="BankDao" ref="bankDao"></property>
    </bean>
    <!--事务控制-->
    <bean id="transationManager" class="utils.TransationManager">
          <property name="ConnectionUtils" ref="connectionUtils"></property>
    </bean>
    
    <bean id="bankDao" class="bank.dao.BankDao">
        <property name="ConnectionUtils" ref="connectionUtils"></property>
    </bean>
    <bean id="connectionUtils" class="utils.ConnectionUtils"></bean>
</beans>

测试

为了检验我们的事务控制是否真的有效,在BankServiceImpl的转账方法里面添加一个错误代码,用来检验是否回滚
在这里插入图片描述
测试test方法

    @Test
    public void transationTest() throws SQLException {
        ProxyFactory proxyFactory = (ProxyFactory) BeanFactory.getBean("proxyFactory");
        BankService bankService = (BankService) BeanFactory.getBean("bankService");
        BankService jdkProxy = (BankService) proxyFactory.getJDKProxy(bankService);
        Boolean transfer = jdkProxy.transfer("6029621011001", "6029621011000", 100);
    }

当前余额
在这里插入图片描述
执行结果f在这里插入图片描述
余额
在这里插入图片描述
执行了回滚,且余额没有变化,没有发生一个变多,而另一个没有减少的情况,事务有效

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值