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动态代理的一些学习心得,如有不对指出,请大家指正,谢谢