结构型模式-----代理模式(Proxy)

1、代理模式

           为其他对象提供一种代理以控制对这个对象的访问。

 

    静态代理:(类似于装饰模式),在代理真实对象进行操作时,可以在操作之前与之后添加额外的操作。

 

      实例一:

 

   

public interface Sender {

	public void send();

}
public class MailSender implements Sender {

	@Override
	public void send() {
		System.out.println(" ~~~~ mailSender ~~~~ ");
	}
}

public class StaticProxy implements Sender {

	private MailSender sender = null;

	public StaticProxy(final MailSender sender) {
		this.sender = sender;
	}

	@Override
	public void send() {
		System.out.println(" ~~~   before  send  ~~~~");
		this.sender.send();
		System.out.println(" ~~~~  after  send ~~~~~~");
	}

}


       模拟测试:

 

     

public class Clinet {

	public static void main(final String[] args) {
		final StaticProxy sp = new StaticProxy(new MailSender());
		sp.send();
	}

}

 

     动态代理:(java从1.3开始引入动态代理,但他只能代码实现了一个或者多个接口的类,并不能直接对类进行动态代理)

 

public interface Sender {

	public void send();

}

public class MailSender implements Sender {

	@Override
	public void send() {
		System.out.println(" ~~~~ mailSender ~~~~ ");
	}
}

public class DynamicProxy implements InvocationHandler {

	private Object object = null;

	public DynamicProxy(final Object object) {
		this.object = object;
	}

	@Override
	public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
		System.out.println(" ~~~   before  send  ~~~~");
		final Object obj = method.invoke(this.object, args);
		System.out.println(" ~~~~  after  send ~~~~~~");
		return obj;
	}
}

 

     模拟使用:

 

     

	public static void main(final String[] args) {
		final Sender sender = new SmsSender();
		final InvocationHandler dp = new DynamicProxy(sender);

		final Sender senderProxy = (Sender) Proxy.newProxyInstance(sender.getClass().getClassLoader(), sender
				.getClass().getInterfaces(), dp);
		senderProxy.send();
	}


         动态代理扩展:如果想对类直接使用动态代理,可以使用CGLIB(Code Generation Library)包。

                  CGLIB是一个强大的高性能的代码生成包。它被许多AOP的框架(例如Spring AOP)使用,为他们提供方法的interception(拦截)。

                  Hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联。EasyMock通过使用模仿(moke)对象来测试java代码的包。

 

                  它们都通过使用CGLIB来为那些没有接口的类创建模仿(moke)对象。其原理是:生成一个要代理类的子类,子类覆盖要代理的类的所有不是final的方法。
             CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。

                   不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。

 

   
        

 


cglib代码包结构
 •core (核心代码) ◦EmitUtils 
◦ReflectUtils 
◦KeyFactory 
◦ClassEmitter/CodeEmitter 
◦NamingPolicy/DefaultNamingPolicy 
◦GeneratorStrategy/DefaultGeneratorStrategy 
◦DebuggingClassWriter 
◦ClassGenerator/AbstractClassGenerator 

•beans (bean操作类) ◦BeanCopier 
◦BulkBean 
◦BeanMap 
◦ImmutableBean 
◦BeanGenerator 

•reflect ◦FastClass 

•proxy ◦Enhancer 
◦CallbackGenerator 
◦Callback ■ MethodInterceptor , Dispatcher, LazyLoader , ProxyRefDispatcher , NoOp , FixedValue , InvocationHandler(提供和jdk proxy的功能) 

◦CallbackFilter 

•util ◦StringSwitcher  
◦ParallelSorter  

•transform  

                      

            实例三、(实现对类的代理)

    

public class Temp {

	public void temp() {
		System.out.println("  ~~~  temp ~~~~~");
	}

}

public class CglibProxy implements MethodInterceptor {

 public Object createProxy(final Object target) {   final Enhancer enhancer = new Enhancer();   // 设置代理目标   enhancer.setSuperclass(target.getClass());   // 设置回调   enhancer.setCallback(this);   enhancer.setClassLoader(target.getClass().getClassLoader());   return enhancer.create();  }

 

 /**   * @param proxy   *            代理类   * @param method   *            被代理的方法   * @param params   *            该方法的参数数组   * @param methodproxy   *            方法的代理   */  @Override  public Object intercept(    final Object proxy,    final Method method,    final Object[] params,    final MethodProxy methodProxy) throws Throwable {   System.out.println(" ~~~   before  send  ~~~~");   final Object o = methodProxy.invokeSuper(proxy, params);   System.out.println(" ~~~~  after  send ~~~~~~");   return o;  } }

   

     模拟调用

  

	public static void main(final String[] args) {
		final Temp temp = new Temp();
		final CglibProxy cp = new CglibProxy();
		final Temp t1 = (Temp) cp.createProxy(temp);
		t1.temp();
	}



 


 

 

 

 

 

 

 



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值