Java动态代理之基于接口实现(JDK动态代理)

1、动态代理的原理

代理设计模式的原理:使用一个代理将原本对象包装起来,然后用该代理对象”取代”原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。

 

Java提供2中动态代理的方式,一种是基于接口实现(JDK动态代理),一种是基于继承实现(Cglib)。

2、基于接口的动态代理模式

JDK代理模式中,有两个重要的点;一个类(Proxy)和一个接口;

2.1、Proxy类是所有动态代理类的父类,可以用户生成动态代理类或者是动态代理类的对象;其下有2个重要的方法,一个是getProxyClass获取代理对象方法和newProxyInstance,获取代理对象实例方法

private static Class getProxyClass0(ClassLoader loader,Class... interfaces)



public static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)

2.2、InvocationHandler接口,主要作用是完成代理的过程;其有一个方法,如下:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;

写个代码理解一下:

首先,写一个目标类对象,因为是基于接口的方式,所以写一个接口类,以及接口的实现类,定义几个方法

public interface UserService {

    public void save(int i,int b);

    public void delete(int i);
}


@Service
public class UserServiceImpl implements UserService {
    @Override
    public void save(int i, int b) {
        System.out.println("我是save方法");
    }

    @Override
    public void delete(int i) {
        System.out.println("我是delete方法");
    }
}

接下来,写动态代理类对象

public class MyProxy{

    /**
     * 目标对象
     * Proxy
     */
    private Object target;


    /**
     * 含有目标对象的构造方法
     */
    public MyProxy( Object object) {
        this.target = object ;
    }

    /**
     * 获取代理对象
     * @return
     */
    public Object getProxy(){
        Object proxy = null;
        /**
         * classLoader,目标类的类加载器
         */
        ClassLoader classLoader = target.getClass().getClassLoader();
        /**
         * interfaces 目标类的接口组
         */
        Class[] interfaces = target.getClass().getInterfaces();
        proxy = Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {

            /**
             *  Object proxy : 代理对象
             *  Method method : 当前正在被代理的方法对象
             *  Object[] args : 方法的参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("动态代理开始了,当前方法为:"+ method.getName()+",当前方法的参数为:"+args);
                Object invoke = method.invoke(target, args);
                System.out.println("动态代理结束了,哈哈哈");
                return invoke;
            }
        });

        return  proxy;

    }
}

编写一个测试类,运行查看结果

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootProxyApplicationTests {

    @Autowired
    private UserService userService;

    @Test
    public void contextLoads() {
        //获取代理对象
        Object proxy = new MyProxy(userService).getProxy();
        //将object类对象强制转换为目标类对象
        userService = (UserService) proxy;
        userService.save(1,2);
        userService.delete(1);

    }

}


//结果
动态代理开始了,当前方法为:save,当前方法的参数为:[Ljava.lang.Object;@24d4d7c9
我是save方法
动态代理结束了,哈哈哈
动态代理开始了,当前方法为:delete,当前方法的参数为:[Ljava.lang.Object;@f0e995e
我是delete方法
动态代理结束了,哈哈哈

以上便是自己在学习Java动态代理是,JDK动态代理的一些学习心得,如有不对指出,请大家指正,谢谢

你可能感兴趣的:(JDK动态代理,java)