本文介绍了三种Java代理模式:静态代理、JDK动态代理和Cglib动态代理。静态代理针对特定接口或对象,需手动编码实现;JDK动态代理通过反射机制实现,适用于所有接口;Cglib动态代理则基于字节码技术,无需接口支持,但需引入外部库。每种方法各有优缺点,选择时应根据具体需求考虑。
1.⭐⭐⭐静态代理🌙🌙🌙
- 基本描述:静态代理代理的是某一个接口的实例对象,以接口的形式对外展示。当然如果不需要以接口的形式对外展示,直接代理对象即可。
- 缺点:只能代理某一种类型,要想代理其他类型,需要修改代码。
package unittest.proxy;
interface StaticInterface{
void method();
}
class Target implements StaticInterface{
@Override
public void method() {
System.out.println("StaticInterface");
}
}
/**
* @author Dylaniou
* 基本描述:静态代理代理的是某一个接口的实例对象,以接口的形式对外展示。当然如果不需要以接口的形式对外展示,直接代理对象即可。
* 缺点:只能代理某一种类型,要想代理其他类型,需要修改代码。
*/
public class JdkStaticProxy implements StaticInterface{
Target target;
JdkStaticProxy(Target target){
this.target = target;
}
@Override
public void method() {
System.out.println("before");
target.method();
System.out.println("after");
}
public static void main(String[] args) {
StaticInterface staticInterface = (StaticInterface)(new JdkStaticProxy(new Target()));
staticInterface.method();
}
}
2.⭐⭐⭐JDK动态代理🌙🌙🌙
- 基本描述:jdk动态代理可以代理的接口的实例对象,以接口的形式对外展示。不局限于某个类型。
- 缺点:必须要有接口。
package unittest.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface DynamicInterface{
void method();
}
class DynamicProxyInterfaceImp implements DynamicInterface{
@Override
public void method() {
System.out.println("DynamicProxyInterfaceImp");
}
}
/**
* @author Dylaniou
* 基本描述:jdk动态代理可以代理的接口的实例对象,以接口的形式对外展示。不局限于某个类型。
* 缺点:必须要有接口。
*/
public class JdkDynamicProxy implements InvocationHandler{
Object target;
JdkDynamicProxy(Object target){
this.target = target;
}
public Object getProxyOfTarget(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before");
method.invoke(target, args);
System.out.println("after");
return null;
}
public static void main(String[] args) {
DynamicProxyInterfaceImp target = new DynamicProxyInterfaceImp();
DynamicInterface dynamicInterface = (DynamicInterface)(new JdkDynamicProxy(target)).getProxyOfTarget();
dynamicInterface.method();
}
}
3.⭐⭐⭐Cglib动态代理🌙🌙🌙
- 基本描述:Cglib动态代理可以直接代理实例对象,不是必须要接口。当然想以接口的形式对外展示也是完全OK的。
- 缺点:Cglib动态代理需要依赖第三方jar包,比如我本地用的就是mybatis-3.5.4里的cglib-3.3.0.jar和asm-7.1.jar。
package unittest.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 CglibInstance{
void method(){
System.out.println("CglibInstance");
};
}
/**
* @author Dylaniou
* 基本描述:Cglib动态代理可以直接代理实例对象,不是必须要接口。当然想以接口的形式对外展示也是完全OK的。
*/
//public class CglibProxy{
public class CglibProxy implements MethodInterceptor{
public Object getProxyOfTarget(Class cls){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(cls);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("before");
methodProxy.invokeSuper(proxy, args);
System.out.println("after");
return null;
}
public static void main(String[] args) {
CglibInstance cglibInterface = (CglibInstance)(new CglibProxy().getProxyOfTarget(CglibInstance.class));
cglibInterface.method();
/*Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(CglibInstance.class);
enhancer.setCallback(new MethodInterceptor(){
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("before");
Object result = methodProxy.invokeSuper(proxy, args);
System.out.println("after");
return result;
}
});
((CglibInstance) enhancer.create()).method();*/
}
}