`
morgan117
  • 浏览: 4172 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Spring 中的代理

阅读更多
Spring中有两种方式进行Bean的代理:
1。JDK 动态代理
   JDK主要通过Proxy.newProxyInstance(Classloader, Interface[], InvocationHandler)方法,生成一个与目标类实现相同接口的代理类,这也是为什么Spring中经常出现ClassCastException: $Proxy can not be cast to xxx. 因为生成的代理类并不是目标类的子类。
    InvocationHandler接口主要包含一个invoke(Object, Method, Object[])方法。第一个参数为生成的代理类,第二个为要执行的方法,第三个为方法参数。

2。Cglib代理
    JDK动态代理只能代理interface,对于没有实现任何接口的类,我们只能使用另一个Cglib代理。Cglib采用非常底层的字节码技术,可以为一个类创建子类。 Cglib的核心类是Enhancer, 它为目标类创建代理实例,并可以通过setCallBack设置回调类(CallBack),最常见的类为MethodInterceptor. 该类的主要方法为intercept(Object, Method, Object[], ProxyMethod)


interface
package inter;

public interface PhoneInterface {
	public void speak();
}


Bean
package Impl;

import inter.Phone;
import inter.PhoneInterface;

import javax.annotation.PostConstruct;

public class IPhone implements PhoneInterface{

	public IPhone(int price, String name) {
		super(price, name);
		System.out.println("param construct");
		
	}
	
	public IPhone() {
		System.out.println("default construct");
	}
	
	@Override
	public void speak(){
		System.out.println(this.getName()+" general speaks ");
		
	}
}


JDK代理-InvocationHandler
package handler;

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

public class MethodHandler implements InvocationHandler {
	private Object target;
	
	public MethodHandler(Object target){
		this.target = target;
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("call Method Name:"+method.getName());
		System.out.println(proxy.getClass());
		Object result = method.invoke(target, args);
		return result;
	}

}



JDK代理- 测试
package handler;

import inter.PhoneInterface;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

import Impl.IPhone;

public class TestJDKProxy {
	
	public static void main(String arg[]){
		IPhone iphone = new IPhone();
		InvocationHandler handler = new MethodHandler(iphone);
		PhoneInterface phone = 	(PhoneInterface)Proxy.newProxyInstance(iphone.getClass().getClassLoader(), IPhone.class.getInterfaces(), handler);
	    phone.speak();
	}

}



Cglib - MethodInterceptor
package cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import Impl.IPhone;

public class CglibProxy implements MethodInterceptor  {
	
	private Enhancer enhancer = new Enhancer();
	
	public Object createProxy(Class c){
		enhancer.setSuperclass(c);
		enhancer.setCallback(this);
	    return	enhancer.create();
		
	}
	

	@Override
	public Object intercept(Object arg0, Method method, Object[] arg2,
			MethodProxy proxy) throws Throwable {
		System.out.println("Method "+method.getName()+" begin");
		Object result = proxy.invokeSuper(arg0, arg2);
		System.out.println("Method "+method.getName()+" end");
		return result;
		
	}

}


Cglib - 测试
package cglib;


import Impl.IPhone;


public class TestCglibProxy {
	
	public static void main(String args[]){
		CglibProxy cgProxy = new CglibProxy();
		
		IPhone phone = new IPhone();
		
//		ApplicationContext context = new FileSystemXmlApplicationContext("/src/beans.xml");
//		
//	    IPhone phone = 	(IPhone)context.getBean("iphone");
	    IPhone p = (IPhone)cgProxy.createProxy(phone.getClass());
	    p.speak();
	    
		
	}
	
}



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics