动态代理?个人理解就是:需要在执行目标类的某个方法之前或之后执行其它类的一些实现方法
实现动态代理的方式,JDK和CGLIB
注意:如果使用JDK实现动态代理,则目标类必须实现一个或多个接口,如果目标类没有实现接口,那么就只有使用CGLIB进行动态代理
经自己研究发现:JDK动态代理返回的Object对象,无法使用反射进行调用,会报java.lang.InstantiationException异常,这说明这个Object对象只能强制转换为目标类的接口,而CGLIB返回的对象可以通过反射进行调用,但是通过反射调用后,代理将失效。会直接调用目标类方法。
代理原理图:
JDK代理实现:
package com.jdk.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 目标类接口
* **/
interface TargetInterface
{
public void targetMethod();
}
/**
* 实现目标类接口
* */
class Target implements TargetInterface
{
@Override
public void targetMethod()
{
System.out.println("Execute Target Mthod .....");
}
}
/**
* 代理类
* */
class ProxyClass
{
public void method_1()
{
System.out.println("Execute ProxyClass Method_1 .....");
}
public void method_2()
{
System.out.println("Execute ProxyClass Method_2 .....");
}
}
/**
* 实现InvocationHandler接口,也就是配置代理类与目标类的执行关系
* */
public class ProxyImpl implements InvocationHandler
{
private Object targetObject;//代理目标类对象
private ProxyClass proxyClass = new ProxyClass();
public ProxyImpl(Object targetObject)
{
this.targetObject = targetObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
Object object = null;
proxyClass.method_1();//调用代理类方法
object = method.invoke(targetObject, args);//调用目标类方法
proxyClass.method_2();//调用代理类方法
return object;
}
public static void main(String args[]) throws Exception
{
//动态代理,返回Object代理对象
//通过代理对象访问代理方法
Object object = Proxy.newProxyInstance(Target.class.getClassLoader(),
Target.class.getInterfaces(), new ProxyImpl(new Target()));
((TargetInterface)object).targetMethod();
System.out.println("\n");
//通过反射调用,报错InstantiationException错误
Class<?> c = object.getClass();
for(Method m:c.getMethods())
{
if(m.getName().equals("targetMethod"))
{
Object o1 = c.newInstance();
m.invoke(o1, null);
break;
}
}
}
}
执行结果:
CGLIB代理实现:
package com.cglib.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
* 实现目标类接口
* */
class Target
{
public void targetMethod()
{
System.out.println("Execute Target Mthod .....");
}
}
/**
* 代理类
* */
class ProxyClass
{
public void method_1()
{
System.out.println("Execute ProxyClass Method_1 .....");
}
public void method_2()
{
System.out.println("Execute ProxyClass Method_2 .....");
}
}
/**
* 实现MethodInterceptor接口,也就是配置代理类与目标类的执行关系
* */
public class ProxyImpl implements MethodInterceptor
{
private Object targetObject;
private ProxyClass proxyClass = new ProxyClass();
public ProxyImpl(Object targetObject)
{
this.targetObject = targetObject;
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable
{
Object object = null;
proxyClass.method_1();
object = arg1.invoke(targetObject, arg2);
proxyClass.method_2();
return object;
}
public static void main(String []args) throws Exception
{
Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(Target.class.getClassLoader());
enhancer.setSuperclass(Target.class);
enhancer.setCallback(new ProxyImpl(new Target()));
Object object = enhancer.create();
((Target)object).targetMethod();
System.out.println("\n");
//通过反射调用,会直接调用目标方法,代理失效
Class<?> c = object.getClass();
for(Method m:c.getMethods())
{
if(m.getName().equals("targetMethod"))
{
Object o1 = c.newInstance();
m.invoke(o1, null);
break;
}
}
}
}
CGLIB执行结果: