一、动态代理有什么用
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)原理是继承来实现:创建子类, 子类就是代理对象,
要求目标类和方法都不可以是final的,