`

静态代理与动态代理

 
阅读更多
代理设计模式

特征:代理类与委托类(被代理类)有同样的接口,代理类负责消息预处理、把消息转发给委托类,以及事后处理消息等。代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

代理类可以分为两种:静态代理和动态代理


静态代理例子:

接口
public interface Count {   
    void queryCount();   
    void updateCount();  
委托类
public class CountImpl implements Count {  
  
    @Override  
    public void queryCount() {  
        System.out.println("查看账户方法...");  
  
    }  
  
    @Override  
    public void updateCount() {  
        System.out.println("修改账户方法...");  
  
    }  
代理类
public class CountProxy implements Count {  
    private CountImpl countImpl;  
   
    public CountProxy(CountImpl countImpl) {  
        this.countImpl = countImpl;  
    }  
  
    @Override  
    public void queryCount() {  
        System.out.println("事务处理之前");  
        // 调用委托类的方法;  
        countImpl.queryCount();  
        System.out.println("事务处理之后");  
    }  
  
    @Override  
    public void updateCount() {  
        System.out.println("事务处理之前");  
        // 调用委托类的方法;  
        countImpl.updateCount();  
        System.out.println("事务处理之后");  
  
    }  
  
}  
测试类
public class TestCount {  
    public static void main(String[] args) {  
        CountImpl countImpl = new CountImpl();  
        CountProxy countProxy = new CountProxy(countImpl);  
        countProxy.updateCount();  
        countProxy.queryCount();  
  
    }  
}  
静态代理的特点:
每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理,而且,所有的代理操作除了调用的方法不一样之外,其他的操作都一样,则此时肯定是重复代码,解决方法是用动态代理实现。


动态代理的例子:

接口
public interface Shape {
void huat();
}
委托类
public class Circle implements Shape {
@Override
public void huat() {
System.out.println("implement Circle");

}
}

动态代理类
public class InvocationHandlerImpl implements InvocationHandler {


private Object target;

        //构造改对象时,要传入相应的委托类对象
public BookFacadeProxy(Object target){
this.target=target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result = null;
System.out.println("事物开始");
// method是传入的方法名称,target表示在此对象上调用该方法,args传入该方法的参数
result = method.invoke(target, args);
System.out.println("事物结束");
return result;
}

}

测试类
public class TestProxy {

public static void main(String[] args) {
Circle c=new Circle();
InvocationHandlerImpl invokeImpl=new InvocationHandlerImpl (c);
                //用Proxy类的静态方法,动态地创建代理对象
                //第1个参数表示加载委托类的类加载器,第2个表示委托类实现的接口
                //第3个表示InvocationHandler类型的对象,是实际代理逻辑实现的地方
Shape s=(Shape)Proxy.newProxyInstance(c.getClass().getClassLoader(), c.getClass().getInterfaces(), invokeImpl);
                //在代理对象上调用方法
s.xi();
}

}

可以看到,采用动态代理,不需要为每个接口编写代理类,代理类对象的生成对所有的接口都是通用的,可以传入不同委托类实例,来生成相应的代理对象。但是,它也有缺点,该方法只能代理实现了接口的类。对没有实现接口的类没法代理。

对没有实现接口的类进行代理,我们可以采用cglib开源框架来实现
例子:
委托类
public class BookFacadeImpl1 {
public void addBook() {
System.out.println("增加图书的普通方法...");
}
}

代理类
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class BookFacadeCglib implements MethodInterceptor {
private Object target;

/**
* 创建代理对象
* @param target
* @return
*/
public Object getInstance(Object target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target.getClass());
// 回调方法
enhancer.setCallback(this);
// 创建代理对象
return enhancer.create();
}

@Override
// 回调方法
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("事物开始");
proxy.invokeSuper(obj, args);
System.out.println("事物结束");
return null;

}

}

测试类
public class TestCglib {
public static void main(String[] args) {
BookFacadeCglib cglib = new BookFacadeCglib();
BookFacadeImpl1 bookCglib = (BookFacadeImpl1) cglib
.getInstance(new BookFacadeImpl1());
bookCglib.addBook();
}
}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics