Skip to main content

动态代理与静态代理

1. 什么是静态代理和动态代理?

图

代理模式是 Java 设计模式,它的特征是代理类与委托类有相同的接口代理类主要负责委托类预处理消息、过滤消息、把消息传递给委托类、以及事后处理消息。代理类与委托类之间捅穿会存在关联关系。一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不是真正服务的实现。而是通过调用委托类的方法来提供相应的服务。

根据代理的创建时期可以分为两种:

  • 静态代理

    由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。静态代理通常只代理一个类,动态代理是代理一个接口下的多个实现类。静态代理事先知道要代理的是什么。

  • 动态代理

    在程序运行时,运用反射机制动态创建而成。动态代理不知道要代理什么东西,只有在运行时才知道

2. 静态代理

上代码:

public interface TestService {

void say(String msg);

}
public class TestServiceImpl implements TestService{
@Override
public void say(String msg) {
System.out.println(msg);
}
}
public class ProxyTestService implements TestService{

private TestService testService;

public ProxyTestService(TestService testService) {
this.testService = testService;
}

@Override
public void say(String msg) {

//预处理
System.out.println("before calling say");
//调用被代理的testService
testService.say(msg);
//事后处理
System.out.println("after calling say");


}
}

执行:

public class Test {

public static void main(String[] args) throws Exception{
TestService service = new TestServiceImpl();
TestService service1 = new ProxyTestService(service);
service1.say("ssssssss");
}

}

通过上面可以看出来静态代理:就是在代理类中进行做数据的前后处理。

3. 动态代理

与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力。

  • JDK原生代理

    上代码:

    public interface TestService {
    void say(String msg);
    }

    public class TestServiceImpl implements TestService{
    @Override
    public void say(String msg) {
    System.out.println(msg);
    }
    }
    public class TestInvocationHandler implements InvocationHandler {

    private Object target;

    public TestInvocationHandler(Object target) {
    this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println(proxy.getClass().getName());
    return method.invoke(target,args);
    }
    }
    public class Test {

    public static void main(String[] args) throws Exception{
    TestService testService = (TestService)Proxy.newProxyInstance(Test.class.getClassLoader(), new Class<?>[]{TestService.class}, new TestInvocationHandler(new TestServiceImpl()));
    testService.say("sssss");
    }

    }
  • cglib代理

public class EnhancerForSampleClassApplication {

public static void main(String[] args) {

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(A.class);
enhancer.setCallback(new MxsmPoxy());
A a = (A)enhancer.create();
a.aaa("bbb");
}

public interface A{

public void aaa(String aaa);

}

public static class MxsmPoxy implements MethodInterceptor{

@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

System.out.println( method.getName());
System.out.println(args[0]);

return null;
}
}
}

cglib的妙用还可以参照Spring核心包的里面的代码。大神的代码值得学习。