代理机制

代理分为静态代理和动态代理,动态代理又有cglib代理和jdk代理之分。

1.静态代理(针对接口):

首先,先定义一个接口,然后实现它,这就是我们的核心代码。
代理机制_第1张图片
一个代理类,用于对实现类进行处理包装:获取其静态代理,并增加附加功能,如:

public class StaticProxy implements IInterface {
	private IInterface realObj = new InterfaceAdpter();
	
	public StaticProxy() {
	}
	
	@Override
	public void show(String str) {
	//代理前后可以增加功能
		System.out.println("代理前~~~~~~");
		realObj.show(str);
		System.out.println("代理后~~~~~~");
	}
}

结果:
代理机制_第2张图片
静态代理很简单,其实就是对接口的应用。根据上面可以发现,为了得到一个代理使用,我需要先有一个接口,再有一个实现类去实现这个接口,再有一个代理类对实现类进行包装处理,十分麻烦。而且一个代理类只能对一个接口的实现类进行包装,如果有多个接口,就要定义多个实现类和代理类。

2.cglib代理

	//生成一个cglib代理
	@SuppressWarnings("unchecked")
	public  T getProxy(T obj) {
		Class klass = obj.getClass();
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(klass);
		enhancer.setCallback(new MethodInterceptor() {
			@Override
			public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
				//object为生成的代理
				Object result = null;
				
				System.out.println("代理前...");
				try {
					//obj为运行方法的对象,args为方法的参数
					result = method.invoke(obj, args);
					System.out.println("代理后...");
				} catch (Exception e) {
					System.out.println("异常时...");
				}
				System.out.println("运行结果:" + result);
				
				return result;
			}
		});

		return (T) enhancer.create();
	}

cglib代理是通过底层的字节码继承要代理的类(父类),扩展该类,生成子类,创建代理。

代理的使用:

public static void main(String[] args) {
	//创建一个tmp类,其中有一些方法,获取该类的代理
	Tmp tmp = new CglibProxy.getProxy(new Tmp());
	//用户使用代理和使用tmp对象时没有任何区别,直接操作就可以
	tmp.fun();
}

此处没有给出测试类和运行结果,大家尝试后可以发现:
cglib代理不要求要代理的类一定为接口的实现类,而且不能对final方法进行处理。

3.jdk代理(针对接口)

一定要注意jdk是面向接口的!!!该方法在创建代理时,速度比cglib要快,但是运行速度比cglib要慢。

@SuppressWarnings("unchecked")
	public  T jdkProxy(Object object) {
		Class klass = object.getClass();
		ClassLoader classLoader = klass.getClassLoader();
		Class[] interfaces = klass.getInterfaces();
		
		InvocationHandler invocationHandler = new InvocationHandler() {
			
			@Override
			public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
				System.out.println("置前拦截...");
				Object result = method.invoke(object, args);
				System.out.println("置后拦截...");
				return result;
			}
		};
		
		return (T) Proxy.newProxyInstance(
					classLoader, interfaces, invocationHandler);
	}

运行结果:
代理机制_第3张图片
在Spring中一般默认使用jdk代理(被代理的对象是个实现类),如果被代理的对没有继承接口,则强制使用cglib动态代理。

你可能感兴趣的:(笔记,代理机制)