Spring框架學習1.0對動態代理的理解z,自定義BeanFactory
阿新 • • 發佈:2019-01-08
自定義一個介面 和一個接實現類
public interface Hello {
void setInfo(String a,String b);
String getInfo();
void hah(String s);
}
/** * Created by likailong on 2016/9/29. */ public class HelloIml implements Hello { private String a; private String b; public void setInfo(String a, String b){ this.a=a; this.b=b; } @Override public String getInfo() { return a; } public void hah(String s){ System.out.print("ssss"+s); } }
動態代理的實現如上程式碼,這只是實現的一種。下面測試上面的程式碼package cn.itcast.shujujiegou.StructuresAnalysis; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * Created by likailong on 2016/9/29. */ public class AopHandler implements InvocationHandler { private Object target; public AopHandler(Object target){ this.target=target; } public void println(String str,Object...args){ System.out.println(str); if(args==null){ System.out.println("沒有傳遞任何值"); }else{ for(Object obj:args){ System.out.println(obj); } } } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("\n\n======呼叫方法名"+method.getName()); Class<?>[] variables=method.getParameterTypes(); System.out.println("\n\t 引數列表:\n"); for(Class<?> typevariables:variables){ System.out.println("\t\t\t"+typevariables.getName()); } println("\n\n\t 傳入引數值為:\n"); for(Object arg:args){ System.out.println("\t\t\t"+arg); } Object result=method.invoke(target,args); println("返回的引數為",result); println("返回的型別為",method.getReturnType()); return result; } }
public class MethodInvokeSample { public static void main(String [] args) throws Exception { Method method=MethodInvokeSample.class.getDeclaredMethod("test",String.class,int.class); String result=(String)method.invoke(null,"fuck",21); System.out.println(result); } public static String test(String a,int b){ return "傳入引數:"+a+"傳入引數:"+b; } }
結果
動態將方法執行並且傳入引數。但是上面沒有展現出面向切面只是動態傳入了一個值下面自定義BeanFactory
package cn.itcast.shujujiegou.StructuresAnalysis;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* Created by likailong on 2016/9/29.
*/
public class BeanFactory {
public static Object getBean(String classname) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Object obj=Class.forName(classname).newInstance();
InvocationHandler handle = new AopHandler(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handle);
}
public static<T> T getBean(String classname,Class<T> clazz) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
return (T)getBean(classname);
}
}
測試
package cn.itcast.shujujiegou.StructuresAnalysis;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by likailong on 2016/9/29.
*/
public class BeanfatoryTest {
public static void main(String [] args) throws IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Hello aa = BeanFactory.getBean("cn.itcast.shujujiegou.StructuresAnalysis.HelloIml", HelloIml.class);
aa.setInfo("hjaslg","sldkjgs");
Method method = Hello.class.getDeclaredMethod("setInfo", String.class, String.class);
method.invoke(new HelloIml(),"aaa","bbb");
}
}
分析newinstance實際原理
從圖看出hello介面是代理指向因此代理物件與實現類無關用了位元組碼增強技術,故代理物件指向介面