一、静态代理
条件:需要目标对象和代理对象实现相同的接口
package com.bycotrun.proxy;
//代理接口类
public interface ProxyInterface {
public String show(String name);
}
package com.bycotrun.proxy;
//代理目标类
public class ProxyImpl implements ProxyInterface {
@Override
public String show(String name) {
System.out.println("目标代理类" + name);
return name;
}
}
package com.bycotrun.proxy;
//静态代理类
public class StaticPorxy implements ProxyInterface {
private ProxyInterface por = new ProxyImpl();
@Override
public String show(String name) {
System.out.println("前置增强");
return por.show(name);
}
}
package com.bycotrun.proxy;
//测试
public class Test {
public static void main(String[] args) {
StaticPorxy por = new StaticPorxy();
por.show("xiaom");
}
}
二、jdk动态代理
条件:需要目标对象和代理对象实现相同的接口
原理:用户调用代理对象的show()方法,代理对象会通过反射调用InvocationHandler对象的invoke()方法,invoke方法在通过反射调用目标对象的show()方法。
package com.bycotrun.proxy;
//jdk动态代理接口类
public interface ProxyInterface {
public String show(String name);
}
package com.bycotrun.proxy;
//jdk动态代理目标类
public class ProxyImpl implements ProxyInterface {
@Override
public String show(String name) {
System.out.println("jdk动态代理目标代理类" + name);
return name;
}
}
package com.bycotrun.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//jdk动态代理类
public class JdkPorxyFactory {
private ProxyInterface por = new ProxyImpl();
public ProxyInterface getPorxy() {
return (ProxyInterface) Proxy.newProxyInstance(por.getClass().getClassLoader(), por.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk动态代理前置");
Object invoke = method.invoke(por, args);
return invoke;
}
});
}
}
package com.bycotrun.proxy;
//测试
public class Test {
public static void main(String[] args) {
JdkPorxyFactory por = new JdkPorxyFactory();
ProxyInterface porxy = por.getPorxy();
String show = porxy.show("xiaom");
System.out.println(show);
}
}
三、cglib动态代理
package com.bycotrun.proxy;
//cglib动态代理目标类
public class ProxyTarget {
public String show(String name) {
System.out.println("cglib动态代理目标代理类" + name);
return name;
}
}
package com.bycotrun.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
//cglib动态代理类
public class CglibProxyFactorry implements MethodInterceptor {
ProxyTarget pro = new ProxyTarget();
public ProxyTarget getProxy() {
Enhancer enhancer = new Enhancer();
// 目标代理类
enhancer.setSuperclass(ProxyTarget.class);
// 回调方法
enhancer.setCallback(this);
// 代理类
ProxyTarget proxy = (ProxyTarget) enhancer.create();
return proxy;
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("cglib动态代理前置");
Object invoke = arg1.invoke(pro, arg2);
return invoke;
}
}
package com.bycotrun.proxy;
//测试
public class Test {
public static void main(String[] args) {
CglibProxyFactorry cglibFactorry = new CglibProxyFactorry();
ProxyTarget proxy = cglibFactorry.getProxy();
String show = proxy.show("xiaom");
System.out.println(show);
}
}
四、动态代理类选择
1、目标对象有接口实现使用jdk动态代理,没有只能用cglib动态代理
2、jdk8以下cglib效率优于jdk动态代理。