JAVA高级基础(61)---代理模式

版权声明:如需转载请标明出处 https://blog.csdn.net/yj201711/article/details/84999561

代理模式

静态代理

代理的实现完全由程序员自己来实现 改实现只能针对特定的对象来实现代理(就是对被代理对象起到一个增强的作用。)

实现步骤

  1. 定义主业务的接口
  2. 实现接口
  3. 通过代理来增强主业务方法
package org.lanqiao.proxy.demo;
//被代理对象
public class Customer implements SallTicket {

	@Override
	public void buyTicket() {
		System.out.println("购买一张太原到北京的动车票");
		
	}

}
package org.lanqiao.proxy.demo;
//代理对象
public class TicketApp implements SallTicket  {
	
	// 需要被代理对象
	private Customer cus ;
	
	//绑定代理对象
	public  TicketApp(Customer  cus) {
		this.cus = cus;
	}
	
	@Override
	public void buyTicket() {
		System.out.println("检查用户是否登陆成功");
		cus.buyTicket();
		System.out.println("收取火车票钱");
		
	}

}
package org.lanqiao.proxy.demo;

public interface SallTicket {
	public  void buyTicket();
}

package org.lanqiao.proxy.demo;

public class Test {
	public static void main(String[] args) {
		Customer cus  = new Customer();
		TicketApp  ta = new TicketApp(cus);
		ta.buyTicket();
	}
}

动态代理:

1、jdk提供的代理的实现:

代理对象必须实现接口(代理的是接口)

步骤

  1. 定义主业务逻辑接口
  2. 实现该接口
  3. 编写针对代理对象的处理方式    implements InvocationHandler

只有这一个方法,还可查询Proxy类 

Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

使用的步骤

  1. 创建被代理对象的实例
  2. 创建代理的处理器对象并绑定被代理对象
  3. 创建代理对象 (被代理对象的接口)
  4. 通过代理对象调用主业务逻辑方法。
package org.lanqiao.jdkproxy.demo;
/*
 * 主业务逻辑接口
 */
public interface BuyTicket {
	public void  buy();
}
package org.lanqiao.jdkproxy.demo;

/*
 * 被代理对象
 */
public class Customer implements BuyTicket {

	@Override
	public void buy() {
		System.out.println("购买一张从太原到北京的火车票");
		
	}

}
package org.lanqiao.jdkproxy.demo;

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

/*
 * 代理对象
 */
public class MyInvocationHandler implements InvocationHandler {
	
	private  Object  target;//代理的目标对象
	//初始化目标对象
	public MyInvocationHandler(Object target) {
		this.target = target;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("检查用户是否登陆成功");
		method.invoke(target, args);
		System.out.println("付款");
		return null;
	}

}
package org.lanqiao.jdkproxy.demo;

import java.lang.reflect.Proxy;

public class Test {
	public static void main(String[] args) {
		Customer  cus = new Customer();//创建代理对象
		MyInvocationHandler Myih = new MyInvocationHandler(cus);//代理的处理方法
		//通过Proxy产生代理接口的对象
		BuyTicket   buyProxy = (BuyTicket) Proxy.newProxyInstance(cus.getClass().getClassLoader(), cus.getClass().getInterfaces(), Myih);
		buyProxy.buy();//通过代理对象调用业务方法
	}
}

2、第三方的代理框架:cglib

Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类,使用CGLIB即使代理类煤与实现任何接口也可以实现动态代理功能。CGLIB具有简单易用,它的运行速度要远远快于JDK的Proxy动态代理

注意:我们所使用的 cglib 不是jdk提供的,是由别人提供的,所以不能直接使用。在使用别人提供的cglib时,别人会将需要的类打包成jar包,如图所示这两个文件,cglib是核心类jar包,asm是依赖类的jar包

把他们复制一下,在项目下新建一个文件夹 lib ,复制到里面去,然后选中这两个jar包右键,找到build path-->Add build path,这样就把jar包加入到我们当前的工程中。(这些步骤是在 eclipse 下完成的)

扫描二维码关注公众号,回复: 4514300 查看本文章

步骤

1、实现主业务逻辑
2、实现 MethodInterceptor方法代理接口,创建代理类
        ① 需要增强器:Enhancer
            // 设置代理类的父类  增强器所要增强的目标类
            en.setSuperclass(clazz);
            //设置回调方法  当增强完成之后 所需要执行的方法
            en.setCallback(this);
            //返回代理对象
            return en.create();//增强之后的对象
        ② 实现interceptor方法
            在执行代理方法之前所需要执行的方法或代码
            使用methodProxy.supperInvoke(被代理对象,方法参数);
            在执行代理方法之后所需要执行的方法或代码
3、使用
        ① 生成代理对象
        ② 通过代理对象获取增强之后的对象  被代理对象
        ③ 增强后的对象执行目标方法

package org.lanqiao.cglib.demo;
/*
 * 被代理对象  主业务逻辑  
 * 使用cglib做代理  不需要实现接口
 */
public class Customer {
	public  void  buyTicket( int money) {
		
		System.out.println("购买一张从太原到北京的动车票");
	}
}
package org.lanqiao.cglib.demo;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/*
 * 代理类  :MethodInterceptor
 */
public class TicketAppCglib 	implements MethodInterceptor{
	// 需要创建增强器
	private Enhancer en = new Enhancer();
	//获取代理对象
	public Object getProxyObj(Class<?> clazz) {
		// 设置代理类的父类  增强器所要增强的目标类
		en.setSuperclass(clazz);
		//设置回调方法  当增强完成之后 所需要执行的方法
		en.setCallback(this);
		
		//返回代理对象
		return en.create();//增强之后的对象
		
		
	}
	//拦截器  对要执行的方法进行拦截
	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		System.out.println("检查用户是否登陆");
		methodProxy.invokeSuper(obj, args);
		System.out.println(args[0]);
		System.out.println("付款");
		return null;
	}

}
package org.lanqiao.cglib.demo;

public class Test {
	public static void main(String[] args) {
		//Customer  cus  = new Customer();
		TicketAppCglib cglib = new TicketAppCglib();
		Customer cusProxy = (Customer) cglib.getProxyObj(Customer.class);
		cusProxy.buyTicket(200);
	}
}

猜你喜欢

转载自blog.csdn.net/yj201711/article/details/84999561