首页 专题 文章 代码 归档
spring手动代理 - jdk动态代理
2020.01.26 11:52 2020.01.26 11:52

1. 手动方式之JDK动态代理

  • JDK动态代理对“装饰者”设计模式简化。使用前提:必须有接口
  • 步骤:
    1. 目标类:接口+实现类
    2. 通知结合(切面类):MyAspect
    3. 有工厂,生成代理类
    4. 测试

1.1. 目标类

接口:

package com.misiai.a_jdk;

public interface UserService {

    public void addUser();

    public void updateUser();

    public void deleteUser();
}

实现类:

package com.misiai.a_jdk;

public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("Add User");
    }

    @Override
    public void updateUser() {
        System.out.println("Update User");
    }

    @Override
    public void deleteUser() {
        System.out.println("Delete User");
    }
}

1.2. 切面类

package com.misiai.a_jdk;

public class MyAspect {

    public void before() {
        System.out.println("前置方法");
    }

    public void after() {
        System.out.println("后置方法");
    }
}

1.3. 工厂类

package com.misiai.a_jdk;

public class MyBeanFactory {

    public static UserService createUser() {
        return new UserServiceImpl();
    }
}

1.4. 测试类

package com.misiai.a_jdk;

import org.junit.Test;

public class JDKTest {

    @Test
    public void test01() {
        UserService userService = MyBeanFactory.createUser();
        userService.addUser();
        userService.updateUser();
        userService.deleteUser();
    }
}

结果:

截图-1580008266

当然,以上只是准备工作,还没有涉及到切面。

2. 工厂类中实现代理

我们现在需要在工厂类中手动实现代理,因为以后全自动的带来也是spring来帮我实现的,而spring就是一个容器(一个工厂)。

代码:

package com.misiai.a_jdk;

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

public class MyBeanFactory {

    public static UserService createUser() {
        //1.目标类
        final UserService userService = new UserServiceImpl();

        //2.切面类
        final MyAspect myAspect = new MyAspect();

        /**
         * 3.代理类,将目标类(切入点)和切面类(通知)结合-->切面
         *
         * Proxy.newProxyInstance
         * 参数1:类加载器 动态代理类,运行时创建,
         *      一般情况下,当前类.class.getClassLoad();
         *      目标实例.getClass().getClassLoader();
         *
         * 参数2:代理类需要实现的所有接口
         * 参数3:InvocationHandler,处理实现类
         *      invoke方法,代理类的每一个方法执行时,都将调用一次invoke
         *      参数31:Object proxy:代理对象
         *      参数32:Method method:代理对象当前执行的方法的描述对象(反射
         *      參数33:object[]args:方法实际参数
         */
        UserService proxyService = (UserService) Proxy.newProxyInstance(
                MyBeanFactory.class.getClassLoader(),
                userService.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 执行切面类前置方法
                        myAspect.before();
                        Object result = method.invoke(userService, args);//返回的是函数的执行结果(返回值)
                        // 后置方法
                        myAspect.after();
                        return result;
                    }
                }
        );


        return proxyService;
    }
}

结果:

截图-1580009414

本节阅读完毕! (分享
二维码图片 扫描关注我们哟