spring jdk 动态代理

spring两种代理方式
若目标对象实现了若干接口,spring使用JDK的java.lang.reflect.Proxy类代理。 
优点:因为有接口,所以使系统更加松耦合 
缺点:为每一个目标类创建接口


若目标对象没有实现任何接口,spring使用CGLIB库生成目标对象的子类。 
优点:因为代理类与目标类是继承关系,所以不需要有接口的存在。 
缺点:因为没有使用接口,所以系统的耦合性没有使用JDK的动态代理好。


今天咱们主要讨论JDK动态代理的方式。JDK的代理方式主要就是通过反射跟动态编译来实现的。

1.创建接口Animal.java

package cn.xxs.proxy;
/**
 * 动物
 * @author xxs
 *
 */
public interface Animal {
	/**
	 * 吃
	 */
	public void eat();

}

2.接口的实现Tiger.java

package cn.xxs.proxy.impl;

import cn.xxs.proxy.Animal;
/**
 * Tiger
 * @author xxs
 *
 */
public class Tiger implements Animal{

	@Override
	public void eat() {
		
		System.out.println("吃肉");
	}

}

3.生成代理对象(proxy)

TigerProxy.java

在JDK动态代理中需要实现接口:java.lang.reflect.InvocationHandler.


首先声明一个类的属性target,它的作用是保存真实服务对象(B);然后用bind方法绑定代理对象(proxy商务)和真实对象(A)。

用之前的比喻就是proxy就是商务,它代理了target(A),而商务代理的逻辑方法放在this这个对象的invoke方法中,只是this这个对象需要实现InvocationHandler接口而已。这样,声明就会进入当前类的invoke方法中,它实现的是代理逻辑,它有三个参数

Object proxy——当前代理对象(商务)

Method method——当前调度的方法

Object[] args——方法参数

然后我们通过反射调度真实对象的方法,Object obj = method.invoke(target, args);//相当于eat方法调用,实现功能。

package cn.xxs.proxy.impl;

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

public class TigerProxy implements InvocationHandler {
	//定义目标对象,也就是被代理对象
	private Object target;

	public Object getTarget() {
		return target;
	}

	public void setTarget(Object target) {
		this.target = target;
	}
	/**
	 * 自定义一些逻辑
	 */
	public void logBegin() {
		System.out.println("记录开始");
	}

	public void logAfter() {
		System.out.println("记录结束");
	}
	/**
	 * proxy:被代理对象
	 * method:被代理对象中的方法名
	 * args:方法对应的参数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//记录动物准备开始吃了
		logBegin();				
		//继续执行被代理对象的方法
		Object obj = method.invoke(target, args);
		//记录结束了
		logAfter();
		return obj;
	}

}

4.打印测试ProxyTest.java

package cn.xxs.test;

import java.lang.reflect.Proxy;

import org.junit.Test;

import cn.xxs.proxy.Animal;
import cn.xxs.proxy.impl.Tiger;
import cn.xxs.proxy.impl.TigerProxy;

public class ProxyTest {
	@Test
	public void test() {
		//创建代理对象
		TigerProxy proxy = new TigerProxy();
		//创建被代理对象
		Animal animal = new Tiger();
		//把被代理对象传到代理对象中,用于invoke
		proxy.setTarget(animal);
		//创建代理对象1.loader类加载器2.被代理对象实现的接口3.实现InvocationHandler类的实例对象
		Animal tiger = (Animal) Proxy.newProxyInstance(animal.getClass().getClassLoader(), new Class[]{Animal.class}, proxy);
		//调用代理类中的方法
		tiger.eat();
	}
}

5.测试结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值