静态代理与动态代理
1.静态代理
注意两点:实现类与代理类实现相同的接口;实现类中拥有的方法,代理类中必须拥有;
Subject.java
public interface Subject {
public void print();
}
RealSubject.java
public class RealSubject implements Subject{
@Override
public void print() {
System.out.println(this.getClass().getName());
}
}
ProxySubject0.java
public class ProxySubject0 implements Subject {
private RealSubject realSubject;
public ProxySubject0(RealSubject realSubject) {
super();
this.realSubject = realSubject;
}
@Override
public void print() {
//附加操作。。。
realSubject.print();
//其他附加操作。。。
}
}
Main0.java
public class Main0 {
public static void main(String[] args){
Subject sub=new ProxySubject0(new RealSubject());
sub.print();
}
}
2.动态代理
2.1 JDK动态代理
主要使用到Proxy类和InvocationHandler接口
Subject.java
public interface Subject {
public void print();
}
RealSubject.java
public class RealSubject implements Subject{
@Override
public void print() {
System.out.println(this.getClass().getName());
}
}
ProxySubject.java
public class ProxySubject implements InvocationHandler{
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject) {
super();
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行动态代理的逻辑
System.out.println("before");
Object result=null;
try{
result=method.invoke(realSubject, args);
}catch(Exception e){
e.printStackTrace();
throw e;
}finally{
System.out.println("after");
}
return result;
}
}
测试类:Main.java
public class Main {
public static void main(String[] args) {
Subject sub=(Subject)Proxy.newProxyInstance(
Main.class.getClassLoader(), new Class[]{Subject.class},new ProxySubject(new RealSubject()));
sub.print();
}
}
2.2 Cglib动态代理
Subject.java
public interface Subject {
public void print();
}
RealSubject.java
public class RealSubject implements Subject{
@Override
public void print() {
System.out.println(this.getClass().getName());
}
}
CglibProxy.java
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxy implements MethodInterceptor{
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before");
Object object=null;
try {
object=proxy.invokeSuper(obj, args);
} catch (Exception e) {
e.printStackTrace();
throw e;
}finally{
System.out.println("after");
}
return object;
}
}
测试类Main0.java
import net.sf.cglib.proxy.Enhancer;
public class Main0 {
public static void main(String[] args) {
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(RealSubject.class);
enhancer.setCallback(new CglibProxy());
Subject subject=(Subject)enhancer.create();
subject.print();
}
}
使用到的jar包:cglib-2.2.2.jar,asm-3.3.1.jar
2.3 jdk动态代理与cglib代理的区别
jdk是基于接口的代理方式,代理的为被代理类的接口的接口方法;
cglib代理是基于继承的代理方式(生成的代理类继承被代理类),无法对static,final类进行代理,无法对private,static方法代理