一、CGlib动态代理
字节码技术:参考:http://note.youdao.com/noteshare?id=13453e8d815d3102938a02881b6f418f&sub=E56D1E6223FC4CA8BF072CD045301EFA
CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。
这是一个需要被代理的类,也就是父类,通过字节码技术创建这个类的子类,实现动态代理。
3. System.out.println("hello everyone");
1.public class CglibProxy implements MethodInterceptor{
2. private Enhancer enhancer = new Enhancer();
3. public Object getProxy(Class clazz){
5. enhancer.setSuperclass(clazz);
6. enhancer.setCallback(this);
11.
public Object intercept(Object obj, Method method, Object[] args,
12.
MethodProxy proxy) throws Throwable {
13.
System.out.println("前置代理");
15.
Object result = proxy.invokeSuper(obj, args);
16.
System.out.println("后置代理");
2. public static void main(String[] args) {
3. CglibProxy proxy = new CglibProxy();
5. SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class);
1.通过实现InvocationHandler接口来自定义自己的InvocationHandler;
2.通过Proxy.getProxyClass获得动态代理类
3.通过反射机制获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)
4.通过构造函数,获得代理对象,并将自定义的InvocationHandler实例对象传为参数传入
publicclass ObjectProxy implements
InvocationHandler {
List<BeforeAdvice> beforeList = new ArrayList<BeforeAdvice>();
List<AfterAdvice> afterList = new ArrayList<AfterAdvice>();
// TODO Auto-generated constructor stub
public ObjectProxy(Object target) {
//解析advice.xml中所有的前置通知--得到class的值--->通过反射得到类的对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse("src//advice.xml");
NodeList beforeNodeList = doc.getElementsByTagName("beforeAdvice");
for(int i=0;i<beforeNodeList.getLength();i++){
Element beforeElement =(Element) beforeNodeList.item(i);
String classValue = beforeElement.getAttribute("class"); //类的完整路径
Class clz = Class.forName(classValue);
BeforeAdvice obj = (BeforeAdvice)clz.newInstance();
NodeList afterNodeList = doc.getElementsByTagName("afterAdvice");
for(int i=0;i<afterNodeList.getLength();i++){
Element afterElement =(Element) afterNodeList.item(i);
String classValue = afterElement.getAttribute("class"); //类的完整路径
Class clz = Class.forName(classValue);
AfterAdvice obj = (AfterAdvice)clz.newInstance();
public Object invoke(Object proxy, Method method, Object[] args)
for(BeforeAdvice bf:beforeList){
Object result = method.invoke(target, args);
for(AfterAdvice af:afterList){
public
static Object getProxyBean(Object obj){
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),new ObjectProxy(obj));
publicstatic
void main(String[] args) {
Idog dog = (Idog)ObjectProxy.getProxyBean(new Dog());