JAVA代理模式--动态代理

    动态代理是为了解决静态代理每次添加新功能都需要新创建代理类的问题。动态代理分为两种,一张是jdk动态代理,一种是cglib动态代理,两种实现动态代理的方法不一样,但是结果是一样的。

1.JDK动态代理

    JDK动态代理创建一个代理类需要实现InvocationHandler接口,接口中有invoke方法,方法有三个参数

   参数1代表被代理的目标对象

   参数2表示被代理目标对象中的方法

   参数3代表参数

package com.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class TicketHandler implements InvocationHandler {

	private Object office;
	
	public TicketHandler(Object office)
	{
		this.office=office;
	}
	
	//proxy被代理的对象
		//method被代理对象的方法
		//args方法参数
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			// TODO Auto-generated method stub
			
			System.out.println("提供茶水,提供无线网络");
			method.invoke(office);
			System.out.println("提供午餐");
			return null;
		}

}
 public static void main( String[] args )
    {
    	TicketOffice office=new TicketOffice();
    	
    	//创建代理对象
    /*	Ticket proxy=new ProxyTicket(office);
    	proxy.SaleTicket();*/
    	
    	Class<?> c=office.getClass();
    	
    	InvocationHandler  handler=new TicketHandler(office);
    	//参数1是类加载器
    	//参数2是实现的接口
    	
    	//创建代理对象
    	Ticket t=(Ticket)Proxy.newProxyInstance(c.getClassLoader(), c.getInterfaces(), handler);
    	t.SaleTicket();
    	
    }
   实现代理需要使用Proxy.newProxyInstance方法创建代理对象。方法同样有三个参数,参数1表示类目标对象加载器,参数2表示目标对象实现的接口。参数3表示添加新功能的handler. 这样同们就可以创建代理对象,并调用目标对象中的方法。但是使用JDK有一个问题,如果目录对象没有继承接口怎么办,我们就没办法使用JDK代理了。JAVA为我们提供了另一种代理方式cglib代理

2.CGLIB动态代理

  cglib动态代理需要实现MethodInterceptor接口,接口中有intercept拦截方法,有四个参数

       参数1表示目标对象的实例

        参数2表示目标对象的方法
        参数3表示方法参数
//参数4表示代理对象
       使用cglib代理目标对象不需要继承接口

    

package com.proxy;

public class Ticket {

	public void SaleTicket() {
		// TODO Auto-generated method stub
         System.out.println("售卖火车票");
	}

}

package com.proxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class cgLibProxy implements MethodInterceptor {

	
	Enhancer hancer=new Enhancer();
	
	
	public Object CreateProxy(Class cls)
	{
		hancer.setSuperclass(cls);//设置创建类的子类
		hancer.setCallback(this);
		return hancer.create();//返回代理对象
	}
	
	//参数1表示目标对象的实例
	//参数2表示目标对象的方法
	//参数3表示方法参数
	//参数4表示代理对象
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("提供茶水,提供WIFI");
		arg3.invokeSuper(arg0, arg2);
		return null;
	}

}

  public static void main( String[] args )
    {
    	
      	cgLibProxy proxy=new cgLibProxy();
      	Ticket t=(Ticket)proxy.CreateProxy(Ticket.class);
      	t.SaleTicket();
}
使用CGLIB代理需要引入CGLIB包

  <!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.4</version>
</dependency>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值