普通代理模式
- 定义一个接口 Subject
- 该接口的实现类 RealSubject
- 代理实现类的类 ProxySubject 实现接口同时内部含有一个实现类的实例
public interface Subject{
void execute();
}
public class RealSubject implements Subject{
@Override
public void execute(){
System.out.println("execute real subject");
}
}
public class ProxySubject implements Subject{
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject){
this.realSubject = realSubject;
}
@Override
public void execute(){
System.out.println("before");
realSuject.execute();
System.out.println("after");
}
}
public class Client{
public static void main(String[] args){
Subject subject = new ProxySubject(new RealSubject());
subject.execute();
}
}
动态代理
分为两种实现
- JDK代理
- Cglib代理
JDK代理
- 定义接口Subject;
- 使用 java.lang.reflect.Proxy 类;
- 代理类实现 InvocationHandler 接口;
注意:只能基于接口进行动态代理。
public interface Subject{
void execute();
}
public class RealSubject implements Subject{
@Override
public void execute(){
System.out.println("execute real subject");
}
}
public class ProxySubject implements InvocationHandler{
private RealSubject realSubject;
public ProxySubject(RealSubject realSubject){
this.realSubject = realSubject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before jdk");
Object result = null;
try {
result = method.invoke(realSubject, args);
} catch (Exception e) {
System.out.println("ex:");
throw e;
} finally {
System.out.println("after jdk");
}
return result;
}
}
public class Client{
public static void main(String[] args){
//生成代理类的实现类
Subject subject = (Subject)Proxy.newProxyInstance(Client.class.getClassLoader(),new Class[]{Subject.class},new ProxySubject(new RealSubject));
subject.execute();
}
}
Cglib代理
通过继承的方法实现。
maven中引入cglib依赖
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.10</version>
</dependency>
继承 MethodInterceptor 接口。
public class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before cglib");
Object result = null;
try {
result = methodProxy.invokeSuper(o, objects);
} catch (Exception e) {
System.out.println("ex:" + e.getMessage());
throw e;
} finally {
System.out.println("after cglib");
}
return result;
}
}
public class Client {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(RealSubject.class);
enhancer.setCallback(new CglibProxy());
Subject subject = (Subject) enhancer.create();
subject.execute();
}
}
jdk和cglib代理比较
- JDK只能通过针对有接口的类的接口方法进行动态代理。
- Cglib基于继承实现动态代理,无法对static、final类进行代理。
- Cglib基于继承实现动态代理,无法对private、static方法进行代理。