什么是动态代理?
假如我有一个user对象,该对象里面有4个方法,增、删、改、查,外界能直接调用这4个方法吗?拿百度来说,你能随便对百度上的内容进行增、删、改、查操作吗?你最多能执行查的操作,增、删、改的操作是不能执行的,你必须要加一个权限操作,应该看看你是否有权限执行这个操作。同理,谁操作了这个东西,你需要给我留下记录,免得我不知道是谁做的。所以,我应该在每一个方法的前面加权限校验,在每一个方法的后面加日志记录。
该怎么做呢?
有人说,很简单,直接在user对象的实现类里面去改,在增、删、改查前面加上权限校验,在后面加上日志记录。你能随便改别人的代码吗?你一改,所以用过user对象的地方都要改,这不乱套了吗?
有人说,可以再重新创建一个user对象,在新对象中加上权限校验和日志记录。确实是这样。但是如果我还有一个学生类,还有一个老师类...等等,你每一个都新创建一个对象的话,太麻烦了,而且没有必要,因为对我来说,我只关心对象的增、删、改、查操作,对于权限校验和日志记录我并不关心,这个时候,我们可以找中介来做权限校验和日志记录的事情,这个中介就是动态代理对象!
动态代理
代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
举例:春季回家买票让人代买
动态代理:在程序运行过程中产生的这个对象
而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理
在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib
Proxy类中的方法创建动态代理类对象
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
最终会调用InvocationHandler的方法
InvocationHandler
Object invoke(Object proxy,Method method,Object[] args)
jdk动态代理
首先定义接口
/**
* 接口
*/
interface IHello {
void sayHello();
}
定义类实现接口和方法
/**
* IHello接口实现类
*/
class Helloimplements IHello {
public void sayHello() {
System.out.println("Hello world!!");
}
}
编写代理类
class JdkProxyTestimplements InvocationHandler {
private Objecttarget;
public JdkProxyTest(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("我是代理之前所做的操作");
Object invoke = method.invoke(target, args);
System.out.println("我是代理之后所做的操作");
return invoke;
}
}
书写主函数调用
public class JdkProxy {
public static void main(String[] args) {
IHello iHello =new Hello();//接口新建所想要代理的类
JdkProxyTest jdkProxyTest =new JdkProxyTest(iHello);
IHello o = (IHello)Proxy.newProxyInstance(iHello.getClass().getClassLoader(), iHello.getClass().getInterfaces(), jdkProxyTest);
o.sayHello();
}
}
CGLIB代理
cglib动态代理需要引入cglib的相关jar包
compilegroup:'cglib',name:'cglib',version:'3.2.10'
/**
* 目标对象,没有实现任何接口
*/
class Singer{
public void sing() {
System.out.println("唱一首歌");
}
}
/**
* 代理类
*/
class ProxyFactoryimplements MethodInterceptor {
private Objecttarget;
public Object getInvoke(){
Enhancer enhancer =new Enhancer();
enhancer.setSuperclass(Singer.class);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)throws Throwable {
System.out.println("执行代理前");
Object invokeSuper = proxy.invokeSuper(obj, args);
System.out.println("执行代理后");
return invokeSuper;
}
}
public class CglibProxy {
public static void main(String[] args) {
ProxyFactory pf =new ProxyFactory();
Singer s = (Singer)pf.getInvoke();
s.sing();
}
}