再谈JDK的动态代理InvocationHandler

Posted sunshine798798

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了再谈JDK的动态代理InvocationHandler相关的知识,希望对你有一定的参考价值。

前言

为什么要再谈,因为动态代理是aop编程的核心。后面分析spring aop的源代码的最重要的理论基础。

再谈动态代理

首先动态代理需要哪些角色呢?

1.抽象角色。这个抽象角色必须为接口。

2.具体角色。这个具体角色必须实现抽象接口。

3.IAdvice接口和BeforeAdviceImple实现类。

4.InvocationHandler的实现类。这个类为动态代理的Handler类。

5.产生代理的接口,抽象类,工厂类。

6.场景类Client。

 

1.我们先新增一个抽象角色ISubject接口。这个接口定义一个方法handle。代码如下所示:

1 package com.example.pattern.proxy.dynamic.second;
2 
3 public interface ISubject {
4 
5     public void handle();
6 }

第5行,定义接口handle。

 

2.定义一个具体角色RealSubject。这个角色实现ISubject接口。代码如下所示:

1 package com.example.pattern.proxy.dynamic.second;
2 
3 public class RealSubject implements ISubject {
4     @Override
5     public void handle() {
6         System.out.println("-----handle-----");
7     }
8 }

第6行,处理handle业务逻辑。

 

3.新增一个通知事件的接口和实现类,代码如下所示。

1 package com.example.pattern.proxy.dynamic.second;
2 
3 public interface IAdvice {
4 
5     public void execute();
6 }
1 package com.example.pattern.proxy.dynamic.second;
2 
3 public class BeforeAdviceImpl implements IAdvice {
4     @Override
5     public void execute() {
6         System.out.println("执行前置通知");
7     }
8 }

 第6行,定义execute业务前置逻辑。

 

4.再来新增一个InvocationHandler的默认处理器。

 1 package com.example.pattern.proxy.dynamic.second;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 public class DefaultInvocationHandler implements InvocationHandler {
 7 
 8     private Object instance = null;
 9 
10     public DefaultInvocationHandler(Object instance) {
11         this.instance = instance;
12     }
13 
14     @Override
15     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
16         return method.invoke(this.instance, args);
17     }
18 }

 第8行,定义被代理对象的实例。

 

5.产生代理的接口,抽象类,实现类。

1 package com.example.pattern.proxy.dynamic.second;
2 
3 import java.lang.reflect.InvocationHandler;
4 
5 public interface IDynamicProxy<T> {
6 
7     public <T> T newProxyInstace(Class<T> clazz, InvocationHandler h);
8 
9 }
package com.example.pattern.proxy.dynamic.second;

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

public abstract class AbstractDynamixProxy<T> implements IDynamicProxy<T> {

    public abstract void before() ;

    @Override
    public T newProxyInstace(Class clazz, InvocationHandler h) {

        this.before();

        ClassLoader classLoader = clazz.getClassLoader();
        Class[] interfaces = clazz.getInterfaces();

        return  (T)Proxy.newProxyInstance(classLoader, interfaces, h);
    }
}
 1 package com.example.pattern.proxy.dynamic.second;
 2 
 3 public class SubjectDynamicProxyImpl<ISubject> extends AbstractDynamixProxy<ISubject>{
 4 
 5     @Override
 6     public void before() {
 7 
 8         IAdvice advice = new BeforeAdviceImpl();
 9         advice.execute();
10 
11     }
12 }

 

6.增加场景类Client。

 1 public class Client {
 2 
 3     public static void main(String[] args) {
 4         ISubject subject = new RealSubject();
 5 
 6         InvocationHandler invocationHandler = new DefaultInvocationHandler(subject);
 7 
 8         ClassLoader classLoader = subject.getClass().getClassLoader();
 9         Class<?>[] interfaces = subject.getClass().getInterfaces();
10 
11         IDynamicProxy<ISubject> dynamicProxy = new SubjectDynamicProxyImpl();
12         ISubject proxyInstance = dynamicProxy.newProxyInstace(subject.getClass(), invocationHandler);
13 
14         proxyInstance.handle();
15     }
16 }

 

以上是关于再谈JDK的动态代理InvocationHandler的主要内容,如果未能解决你的问题,请参考以下文章

JDK的动态代理与cglib动态代理

JDK动态代理CGLIB动态代理

JDK动态代理CGLIB动态代理

JDK动态代理深入理解分析并手写简易JDK动态代理(上)

JDK动态代理[2]----JDK动态代理的底层实现之Proxy源码分析

细说JDK动态代理的实现原理