动态代理之jdk代理

动态代理有jdk动态代理及cglib代理,下面描述jdk动态代理

jdk动态代理

看了 上云 老师的视频,整理下

pom文件


        
            org.springframework.boot
            spring-boot-starter-web
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
            junit
            junit
        

目标类  IStudentServiceImpl

//目标执行接口
public interface IStudentService {

    void save();

    List query();
}


//目标执行类实现
@Service
public class IStudentServiceImpl implements IStudentService {

    private static final Logger logger= LoggerFactory.getLogger(IStudentServiceImpl.class);

    @Override
    public void save() {
        logger.info("新增功能...");
    }

    @Override
    public List query() {
        logger.info("查询功能...");
        return new ArrayList<>();
    }
}

增强类 TransactionService


@Service
public class TransactionService{

    private static final Logger logger= LoggerFactory.getLogger(TransactionService.class);

    public void before(){
        logger.info("开始事务...");
    }

    public void after(){
        logger.info("结束事务...");
    }

}

代理类


public class TransactionHandler implements InvocationHandler {

    private Object obj; //目标对象

    private TransactionService transactionService; //增强方法

    public TransactionHandler(Object obj, TransactionService transactionService) {
        this.obj = obj;
        this.transactionService = transactionService;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        if ("save".equals(method.getName())) {
            transactionService.before();
            result = method.invoke(obj,args);
            transactionService.after();
        } else {
            result = method.invoke(obj,args);
        }
        return result;
    }
}

Junit测试类


public class TestStudent {

    @Test
    public void test(){
        //增强类
        TransactionService transactionService=new TransactionService();
        //目标类对象
        IStudentService studentService=new IStudentServiceImpl();
        //方法拦截处理器
        TransactionHandler transactionHandler = new TransactionHandler(studentService, transactionService);
        //获取代理实例对象
        IStudentService proxyInstance = (IStudentService)Proxy.newProxyInstance(IStudentServiceImpl.class.getClassLoader(), IStudentServiceImpl.class.getInterfaces(), transactionHandler);
        proxyInstance.save();
        saveProxyClass("D:\\programs\\idea\\projects\\demo1\\src\\");
    }

    private void saveProxyClass(String path){
        byte[] proxy1s = ProxyGenerator.generateProxyClass("$Proxy1", IStudentServiceImpl.class.getInterfaces());
        FileOutputStream out=null;
        try {
            out=new FileOutputStream(new File(path+"$Proxy1.class"));
            out.write(proxy1s);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(out!=null){
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

结论

可以看到:在src目录下生成一个class类[$Proxy1.class],此文件可以看到 该代理子类通过调用InvocationHandler的invoke方法实现了目标类的方法。

动态代理之jdk代理_第1张图片

$Proxy1.class文件内容如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import com.example.demo.service.IStudentService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.List;

public final class $Proxy1 extends Proxy implements IStudentService {
    private static Method m1;
    private static Method m3;
    private static Method m4;
    private static Method m2;
    private static Method m0;

    public $Proxy1(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void save() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final List query() throws  {
        try {
            return (List)super.h.invoke(this, m4, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("com.example.demo.service.IStudentService").getMethod("save");
            m4 = Class.forName("com.example.demo.service.IStudentService").getMethod("query");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

由此可得出结论:底层实现了个Proxy的子类,Proxy里面有需要实现的增强方法,通过反射机制生成一个子类实现InvocationHandler接口,实现动态代理。
通过代理类对象调用方法时,会先调用其重写的invoke方法,里面再调用原方法。

  • 通过实现接口获取到接口的所有方法[$Proxy1.class文件实现目标IStudentService类]
  • 通过Proxy创建代理类实例[Proxy.newProxyInstance]
  • 通过反射机制,获取到一个个的方法对象[$Proxy1.class类]
  • 调用invocationHandler接口的invoke方法,从而实现业务的增强[TransactionHandler类文件实现InvocationHandler]

你可能感兴趣的:(面试专用,java)