第3章AOP 面向切面编程(不使用AOP时,动态代理源码编写)

Step1 :项目 aop_leadin1         
       先定义好接口与一个实现类,该实现类中除了要实现接口中的方法外,还要再写两个非 业务方法。非业务方法也称为交叉业务逻辑:
➢ doTransaction():用于事务处理
➢ doLog():用于日志处理
然后,再使接口方法调用它们。接口方法也称为主业务逻辑。
接口:

 

Step2 :项目 aop_leadin2
        当然,也可以有另一种解决方案:将这些交叉业务逻辑代码放到专门的工具类或处理类 中,由主业务逻辑调用。

Step3:项目 aop_leadin3

       以上的解决方案,还是存在弊端:交叉业务与主业务深度耦合在一起。当交叉业务逻辑 较多、时,在主业务代码中会出现大量的交叉业务逻辑代码调用语句,大大影响了主业务逻辑 的可读性,降低了代码的可维护性,同时也增加了开发难度。
      所以,可以采用动态代理方式。在不修改主业务逻辑的前提下,扩展和增强其功能。
功能增强:

项目结构

项目展示

1.创建SomeService接口

package com.it.service;

public interface SomeService {
    void doSome();
    void doOther();
}

2.创建SomeServiceImpl实现类

package com.it.service.impl;

import com.it.service.SomeService;
import com.it.util.ServiceTools;

import java.util.Date;
//现在是基本的增加方法中的功能,会改变原有代码的逻辑
//如果使用动态代理,就可以在不修改原来代码的前提下,额外的增加功能。

/**
 * 动态代理:在程序执行的过程中,创建代理对象,通过代理对象执行方法,给目标类中的方法增加额外功能。
 */


public class SomeServiceImpl implements SomeService {
    @Override
    public void doSome() {

        System.out.println("执行了业务方法的doSome()");

    }

    @Override
    public void doOther() {

        System.out.println("执行了业务方法的doOther()");

    }
}

3.创建ServiceTools工具类

package com.it.util;

import java.util.Date;

public class ServiceTools {
public static void doLog(){
    System.out.println("当前执行时间为:"+new Date());
}
public static void doCommit(){
    System.out.println("提交事务");
}
}

4.创建MyInvocationHandler动态代理类

package com.it.handler;

import com.it.util.ServiceTools;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {
//    因为是动态代理,目标对象是活动的,所以定义一个变量用来保存目标
    private Object target;//target目标对象,最终会是SomeServiceImpl类


    public MyInvocationHandler(Object target) {
        this.target = target;
    }

    @Override
//    代理对象在执行方法时,会调用这个invoke()方法。
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        System.out.println("执行了MyInvocationHandler类中的invoke()");
        //下面的方法有返回值,要进行一个记录
        Object res=null;
        ServiceTools.doLog();
//        invoke()方法主要是执行目标类中的方法,通过Method类实现
        res=method.invoke(target,objects);//SomeServiceImpl.doSome(),doOther();
        ServiceTools.doCommit();
//        返回目标方法返回结果
        return res;
    }
}

5.创建动态代理测试类

package com.it;

import com.it.handler.MyInvocationHandler;
import com.it.service.SomeService;
import com.it.service.impl.SomeServiceImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {

//        使用jdk的Proxy创建代理对象
//        首先创建目标对象
        SomeService target=new SomeServiceImpl();
//        创建InvocationHandler对象
        InvocationHandler handler=new MyInvocationHandler(target);
//        使用Proxy创建对象
/**
 *  格式是固定的, newProxyInstance()的第一个参数是目标类的类加载器,
 *  第二个参数是目标类实现了那些接口
 *  第三个参数是该代理类要执行的功能
  */
//代理的是SomeService接口中的功能,所以要强转一下
        SomeService proxy= (SomeService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                handler);
//        通过代理执行方法,会调用handler中的invoke()方法
        proxy.doSome();
        proxy.doOther();

    }
}

项目测试结果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

做一道光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值