Spring 中的代理

Spring中有两种方式进行Bean的代理:
1。JDK 动态代理
JDK主要通过Proxy.newProxyInstance(Classloader, Interface[], InvocationHandler)方法,生成一个与目标类实现相同[b]接口[/b]的代理类,这也是为什么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();


}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值