Java基础之代理

Java中代理的定义

给目标对象提供一个代理对象,并且让代理对象控制对目标对象的引用。

代理的目的

  1. 通过代理增强原来的功能;
  2. 通过代理对象间接访问目标对象,防止出现一些不必要的问题。

相关概念

目标类:就是我们要访问的原对象。

代理类:代理模式产生的对象,原对象的“替身”,在原有逻辑上修改逻辑。

 代理可分为两种:静态代理动态代理

1.静态代理

特点:

  1. 所有的代理类都是自己手动去实现的;
  2. 代理类所代理的目标对象都是固定的。

 利用接口实现静态代理

关于接口的方式,我们在实现接口的时候,目标类和代理类都必须实现目标接口当中所实现的方法,从某种意义上代理类就可以帮我们实现目标类当中的方法,并且代理类还可以有自己的扩展方法。

 Java代码实现

首先需要定义一个接口。

public interface ByClothes {
	void clothes(String size);
}

接下来定义一个目标对象。

public class ClothesFactory implements ByClothes {
	@Override
	public void clothes(String size) {
		System.out.println("已经为您制作好了一整套size为"+size+"的衣服。。。。。。。。");
	}
}

 再定义一个代理对象。

public class proxy implements ByClothes {

	//被包含的真是对象
	public ClothesFactory factory = new ClotheFactory;
	// 对功能的增强
	@Override
	public void clothes(String size) {
		FrontService();
		factory.clothes(size);
		endService();
	}
	
	//前置服务
	public void FrontService() {
		System.out.println("根据您的需求进行市场调研");
	}

	//前置服务
	public void endService() {
		System.out.println("为您提供一条龙的包办服务");
	}
}

再写一个测试类测试一下。

public class Test {
	public static void main(String[] args) {
		ClothesFactory clothesFactory = new ClothesFactory();
		proxy proxy = new proxy(clothesFactory);
		proxy.clothes("XXl");
	}
}

静态代理逻辑图 

 静态代理出现的问题

  1. 当目标类很多时,代理类也需要很多,这样就会造成类的繁多;
  2. 当修改接口当中的代码时,都会对其他的类造成影响,违背开闭原则(程序对访问开放,对修改关闭)。

2.动态代理

动态代理是采用JDK提供的方法创建代理对象。

动态代理的实现

  1. jdk动态代理:使用java反射包当中的类和接口实现动态代理的功能;

  2. cglib动态代理:cglib是是第三方的工具库。其原理是继承,cglib通过继承目标类,创建他的子类,在子类当中重写父类的相关方法,实现功能的增强。

 Java代码实现(JDK)

首先还是要新建一个接口。

public interface ByShoot {
	void byShoot(String size);
}

然后新建一个工厂。

public class ShootFactory implements ByShoot{

	@Override
	public void byShoot(String size) {
		System.out.println("已经为您生产出了尺码为"+size+"的鞋子");
	}
}

再新建一个代理类。

public class LisiFactory implements InvocationHandler {

	// 被代理的对象
	private Object factory ;

	public Object getFactory() {
		return factory;
	}

	public void setFactory(Object factory) {
		this.factory = factory;
	}
    
    
    //三个参数的讲解
    //1.Object:jdk创建的代理类,无需赋值
    //2.Method:目标类当中的方法,jdk提供,无需赋值
    //3.Object[]:目标类当中的方法的参数,jdk提供,无需赋值
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		FrontService();
		method.invoke(factory, args);  //这里的invoke(目标对象,方法参数)
		endService();
		return null;
	}

	// 前置服务
	public void FrontService() {
		System.out.println("根据您的需求进行市场调研");
	}

	// 后置服务
	public void endService() {
		System.out.println("为您提供一条龙的包办服务");
	}
 
 	//该方法并不是固定的,但是内部的Proxy类的创建是核心
	public Object getProxyInstance() {
		// TODO Auto-generated method stub
		return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
	}
}

代理类实现的一些细节

1. InvocationHander接口当中只有一个invoke()方法。

     invoke()方法里面是代理对象要实现的功能,即调用执行目标方法与增强目标对象的功能。

2. Proxy类是核心对象,目的是创建代理对象(代替了new)。

3. newProxyInstance()方法是创建代理对象,它的返回值就是一个代理对象。

// ClassLoader loader:类的加载器,复杂向内存当中加载对象,使用反射的方式获取
// Class<?>[] interfaces:目标对象实现的接口,也是反射获取
// InvocationHandler h:代理类需要完成的功能
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)

最后写一个测试类来测试一下。

public class Test {
	public static void main(String[] args) {
		ClothesFactory clothesFactory = new ClothesFactory();
		ShootFactory shootFactory = new ShootFactory();
		LisiFactory lisiFactory = new LisiFactory();
		lisiFactory.setFactory(shootFactory);
		ByShoot yuangong1 = (ByShoot) lisiFactory.getProxyInstance();
		yuangong1.byShoot("42");
		lisiFactory.setFactory(clothesFactory);
		ByClothes yuangong  = (ByClothes) lisiFactory.getProxyInstance();
		yuangong.clothes("XXL");
	}
}

输出结果:

根据您的需求进行市场调研
已经为您制作好了一整套size为XXL的衣服。。。。。。。。
为您提供一条龙的包办服务
根据您的需求进行市场调研
已经为您生产出了尺码为45的鞋子
为您提供一条龙的包办服务

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Beau Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值