代理分为静态代理和动态代理,静态代理是在编译时就将接口、实现类、代理类一股脑儿全部手动完成,但如果我们需要很多的代理,每一个都这么手动的去创建实属浪费时间,而且会有大量的重复代码,此时我们就可以采用动态代理,动态代理可以在程序运行期间根据需要动态的创建代理类及其实例,来完成具体的功能。
其实方法直接调用就可以完成功能,为什么还要加个代理呢?
其实方法直接调用就可以完成功能,为什么还要加个代理呢?
原因是采用代理模式可以有效的将具体的实现与调用方进行解耦,通过面向接口进行编码完全将具体的实现隐藏在内部。
通过代码,来大概感受下两种代理的不同。
(1)静态代理:
public class StaticProxy {
public static void main(String[] args) {
SuperMan superMan = new StaticProxy().new SuperMan();
StaticProxyClass staticProxyClass = new StaticProxy().new StaticProxyClass(superMan);
staticProxyClass.fly();
}
//业务接口
interface Human{
public void info();
public void fly();
}
//纯业务接口的实现类
class SuperMan implements Human{
@Override
public void info() {
System.out.println("我是超人");
}
@Override
public void fly() {
System.out.println("我会飞");
}
}
class HumanUtil{
public void method1(){
System.out.println("-------开始--------");
}
public void method2(){
System.out.println("-------结束--------");
}
}
//静态代理类(在纯业务基础上增加附加业务)
class StaticProxyClass implements Human{
Human human;
HumanUtil humanUtil = new HumanUtil();
public StaticProxyClass(Human human){
this.human = human;
}
@Override
public void info() {
humanUtil.method1();
human.info();
humanUtil.method2();
}
@Override
public void fly() {
humanUtil.method1();
human.fly();
humanUtil.method2();
}
}
}
(2)动态代理模式:
public class DynamicProxy {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
DynamicProxyClass dynamicProxyClass = new DynamicProxyClass();
Object object = dynamicProxyClass.getObject(superMan);
Human human = (Human) object;
human.info();
System.out.println("=====================");
human.fly();
}
}
//业务接口
interface Human{
public void info();
public void fly();
}
//纯业务接口的实现类
class SuperMan implements Human{
@Override
public void info() {
System.out.println("我是超人");
}
@Override
public void fly() {
System.out.println("我会飞");
}
}
class HumanUtil{
public void method1(){
System.out.println("-------开始--------");
}
public void method2(){
System.out.println("-------结束--------");
}
}
class DynamicProxyClass implements InvocationHandler{
Object obj;
HumanUtil humanUtil = new HumanUtil();
public Object getObject(Object obj){
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
humanUtil.method1();
Object returnValue = method.invoke(obj, args);
humanUtil.method2();
return returnValue;
}
}