java代理

代理的定义:给目标对象提供一个代理对象,并且由代理对象控制着目标对象的引用

目的:

1)功能增强,通过代理对象对原业务进行增强。

2)控制访问,通过代理对象间接访问目标对象,防止直接访问目标对象给系统带来不必要复杂性

怎么实现代理?

有两种方式:

1)静态代理:

2)动态代理:动态代理有两种方式,一种是基于jdk动态代理,另一种是spring框架里的cglib动态代理。

静态代理:利用接口实现静态代理

先通过接口定义好我们需要代理的方法,再写一个代理类来实现我们要代理的目标对象有哪些,等要实现一个目标对象时我们需要添加一个目标对象,再把目标对象在代理类里进行实例化。我们看以下例子:

根据上面所说,先写一个接口(生产衣服的接口),定义需要代理的方法:

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

再写一个代理类:

public class Daili implements Byclothes{
	

	@Override
	public void clothes(String size) {
		// TODO Auto-generated method stub
		//实现的接口方法,在需要代理时可以调用
	}
	public void start() {
		System.out.println("前置服务");
	}
	public void end() {
		System.out.println("后置服务");
	}
	
}

这时我们需要生产一件衣服,要通过代理类进行代理,我们写一个目标类clothA:

public class ClothA implements Byclothes{

	@Override
	public void clothes(String size) {
		// TODO Auto-generated method stub
		System.out.println("你添加了一件"+size+"的衣服");
	}
	
}

此时我们需要代理类来进行代理,我们就需要在代理类里进行实例化,再在方法里进行具体实现,我们看以下代码:

public class Daili implements Byclothes{
	private ClothA a=new ClothA();

	@Override
	public void clothes(String size) {
		// TODO Auto-generated method stub
		start();
		a.clothes(size);
		end();
	}
	public void start() {
		System.out.println("前置服务");
	}
	public void end() {
		System.out.println("后置服务");
	}
	
}

我们发现静态代理很麻烦,每当需要添加一个目标对象时,我们都需要进行大量的代码整理,违背了开闭原则,所以一般都通过动态代理进行实现代理

基于jdk的动态代理:

基于jdk的动态代理里用到了jdk里封装好的一个接口,叫做InvocationHandler,我们通常在代理类里来实现这个接口,再来实现接口里的invoke方法,反射里经常用到invoke来调用方法,这里是同样的道理。

@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
}

看如上代码,invoke方法里proxy代表要代理的目标类,method代表目标类中的方法,args代表目标类当中的方法参数。

通过上面的解释,我们需要在这个从接口里继承来的invoke方法里用method.invoke(创建的目标类, args);这个方法来调用我们的目标类的方法。

我们还用之前写的bycloth接口和clothA目标类,

我们写的代理类如下:

public class ProxyFactory 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);//执行目标类当中的方法
        endService();
        return null;
    }

    //该方法并不是固定的,但是内部的Proxy类的创建是核心

    /**
     * 1.ClassLoader loader : 类的加载器:像内存当中加载对象,使用反射的方式获取
     * 2.Class<?>[] interfaces:获取目标类的接口,使用反射的方式获取---------》方法
     * 3.InvocationHandler h:让代理类知道被代理的方法
     * @return
     */
    public Object getProxyInstance() {
        // TODO Auto-generated method stub
        return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
    }

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

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


	
}

我们定义的getproxyinstance方法是整个代理类的核心,用来调用invoke方法

我们再用test类对代理类进行测试:

public class Test {
	public static void main(String[] args) {
		ProxyFactory proxyFactory=new ProxyFactory();
		ClothA A=new ClothA();
		proxyFactory.setFactory(A);
		Byclothes byclothes=(Byclothes)proxyFactory.getProxyInstance();
		byclothes.clothes("xxl");
	}
}

输出结果如下:

如果再添加需要代理的目标类时,我们直接在test类里进行调用就可以而不用再在代理类里再写。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sshm_666

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

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

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

打赏作者

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

抵扣说明:

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

余额充值