一、动态代理有什么用
1、他能创建对象 2、在原有代码不变不改动的情况下,对原有功能进行增强(有点想装饰者模式) 3、解耦合,让你的业务功能和日志,分离
二、两种实现方式
(1)、JDK动态代理:
通过这三个类 Proxy,method,invocationhandler来实现。 要求目标类必须实现接口
(2)、CGLIB 动态代理
原理是继承 通过创建子类,来重写父类的方法,来达到增强目标类方法。
1、JDK动态代理
开发步骤: 1、创建目标类,SomeServiceImpl 目标类 2、创建InvocationHandler 接口的实现类,在这个类实现给目标方法增强功能 3、使用jdk中类proxy,创建代理对象,实现创建对象的能力
接下来开始代码的演示:
创建目标类接口 SomeService
package com.mr.lee.service; public interface SomeService { public String doSome(); public String doOther(); }
创建目标实现类 SomeServiceImpl
package com.mr.lee.service; public class SomeServiceImpl implements SomeService{ @Override public String doSome() { System.out.println("执行了doSome方法"); return "abc"; } @Override public String doOther() { System.out.println("执行了doOther方法"); return "abc"; } }
创建MyInvocationHandler类,来实现InvocationHandler接口, 该类的目的就是用来给目标方法增强功能
package com.mr.lee.dao; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 实现InvocationHandler接口,用来给目标方法增强功能 */ public class MyInvocationHandler implements InvocationHandler { //目标对象 private Object target; public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //通过代理对象执行方法时,会执行这个invoke方法 Object res = null; //执行目标类的方法,通过method类实现 System.out.println("当前执行的方法是:" + method.getName()); if(method.getName().equals("doSome")){ System.out.println("当前执行时间:" + System.currentTimeMillis()); res = method.invoke(target,args);//相当于SomeServiceImpl.doSome()方法 System.out.println("执行结束时间:" + System.currentTimeMillis()); return res; } return method.invoke(target,args);//相当于SomeServiceImpl.doSome()方法 } }
测试了跑一下
package com.mr.lee; import com.mr.lee.dao.MyInvocationHandler; import com.mr.lee.service.SomeService; import com.mr.lee.service.SomeServiceImpl; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class AppTest { @Test public void shouldAnswerWithTrue() { SomeService target = new SomeServiceImpl(); InvocationHandler handler = new MyInvocationHandler(target); //使用Proxy创建代理对象 SomeService proxy = (SomeService) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler ); //通过代理执行方法,会调用handler中的invoke方法 proxy.doSome(); proxy.doOther(); } }
执行结果
当前执行的方法是:doSome 当前执行时间:1664091059671 执行了doSome方法 执行结束时间:1664091059671 当前执行的方法是:doOther 执行了doOther方法 Process finished with exit code 0
2、CGLIB 动态代理
(1)APO底层的实现就是动态代理,AOP就是对动态代理进行的一种规范化。 (2)原理是继承来实现:创建子类, 子类就是代理对象, 要求目标类和方法都不可以是f