静态代理
静态代理使用场景
在实际使用中,经常会遇到一些场景:想在多方法前或方法后加一个共同的方法,如在方法执行前后打印日志、在方法执行完成发送消息通知等。这个时候,我们可以在方法前后调用公用方法,也可以使用代理实现,当然,代理的作用不止如此,这里不做赘述,实现方法如下:
实现方法
先创建一个接口
代码语言:javascript复制public interface TestInterface {
void showMessage();
}
创建一个具体的类,实现这个接口,再创建一个代理类,也实现这个接口
代理类加一个有参构造方法,创建代理类对象的时候传具体类对象即可
代码语言:javascript复制// 具体类
public class TestImpl implements TestInterface {
@Override
public void showMessage() {
System.out.println("message");
}
}
// 代理类
class TestProxy implements TestInterface {
private TestInterface testInterface;
public TestProxy(TestInterface testInterface) {
this.testInterface = testInterface;
}
@Override
public void showMessage() {
printLogBefore();
testInterface.showMessage();
printLogAfter();
}
private void printLogBefore() {
System.out.println("logger before");
}
private void printLogAfter() {
System.out.println("logger after");
}
}
调用代理类
代码语言:javascript复制public static void main(String[] args) throws Exception {
TestProxy t = new TestProxy(new TestImpl());
t.showMessage();
}
执行结果
logger before message logger after
JDK动态代理
静态代理的具体类与代理类的对应关系是一对一,那么动态代理可以理解为多对多
动态代理是通过反射实现的
实现方法:
先创建一个接口
代码语言:javascript复制public interface TestInterface {
void showMessage();
}
创建一个具体的类,实现这个接口,再创建一个代理类,这里与静态代理不同,动态代理的代理类实现的是java.lang.reflect.InvocationHandler接口
被代理类
代码语言:javascript复制public class TestImpl implements TestInterface {
@Override
public void showMessage() {
System.out.println("show message");
}
}
代理类
代码语言:javascript复制public class TestProxy<T> implements InvocationHandler {
private T obj;
public T build(T obj) {
this.obj = obj;
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
printLogBefore();
method.invoke(obj, args);
printLogAfter();
return null;
}
private void printLogBefore() {
System.out.println("print log before");
}
private void printLogAfter() {
System.out.println("print log after");
}
}
调用方法
代码语言:javascript复制public static void main(String[] args) {
TestInterface t = new TestProxy<TestInterface>().build(new TestImpl());
t.showMessage();
}
返回结果
print log before show message print log after
静态代理与动态代理的区别
- 静态代理是在编译时已经创建好的,动态代理是在程序运行过程中通过反射创建的
- 静态代理在运行前就知道是代理哪个类,而动态代理需要在运行的时候才能确定
- 静态代理通常只代理一个类,而动态代理可以代理接口下所有类
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/183834.html原文链接:https://javaforall.cn