1. 程式人生 > >黑馬程式設計師--java高新技術 26--javaBean,泛型,類載入器,代理spring小框架

黑馬程式設計師--java高新技術 26--javaBean,泛型,類載入器,代理spring小框架

---------------------- ASP.Net+Android+IO開發S.Net培訓、期待與您交流! ----------------------

/*設計模式:
Singleton:	單例模式
Factorty:	工廠模式
Iterator:	迭代器模式
Template:	模板模式
Coposite:	組合模式
Proxy:		代理模式
Decrator:	裝飾模式
Flyweight:	享元模式
*/

//26-30

class  
{
	public static void main(String[] args) 
	{
		ReflectPoint pt1 = new ReflectPoint(3,5);
		String propertyName = "x";

		Object retVal = getProperty(pt1,propertyName);
		System.out.println("Hello World!");
	}

	private static Object getProperty(Object pt1,String propertyName) throws IntrospectionException,IllegalAccessException,InvocationTargetException{
		PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
		Method methodGetX = pd.getReadMethod();
		Object retVal = methodGetX.invoke(pt1);
		return retVal;
	}
}

/*26-32 BeanUtils 工具包
r(工程\lib\jar檔案)--build path--add to build path  //增加自定義的jar檔案 referenced Libraries。
	//jar 檔案 直接複製到 lib 資料夾下。

commons-beanutils.jar
commons-logging-1.1.jar

Map map = {name:"ddf",agd:18};
BeanUtils.setProperty(map,"name","adf");

PropertyUtils.setProperty(pt1,"x",9);

BeanUtils 以字串的型別 對資料進行操作。支援屬性鏈的操作
PropertyUtils 以原有屬性型別進行對資料進行操作。
*/

/*26-33
1.5新特性:註解


javac -xlint:deprecation xxx.java	//檢視過時的方法
@SuppressWarning("deprecation")  //不提示 已過時資訊。
@Deprecated		//用於標記該方法過時了

集合的equals方法 傳入的引數是Object型別的引數。

java.lang 的註解
Deprecated
Override
SuppressWarning

加了註解就等於給程式打上了某種標記。

註解可以加在 包,類,成員變數,方法,方法的引數,區域性變數
*/

/*26-34
註解相當於 一個特殊的 類

註解的應用
	註解類
	應用了註解的類
	對 應用了註解的類 進行反射的類

AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class);
AnnotationTest.class.getAnnotation(ItcastAnnotation.class);

@Retention(RetentionPolicy.RUNTIME)  //元註解

註解的生命週期:
	原始檔,class檔案,記憶體中的位元組碼
	預設在保留到class檔案


@Target({ElementType.METHOD,Element.TYPE})
*/

/*26-35 為註解增加屬性
當僅有一個需要賦值的屬性是可以省略 "屬性="

Annotation annotationAttr default @MetaAnnotation("ihm");  //註解的元素是註解型別的值
*/

/*26-37
泛型是提供給javac使用的

因此通過反射新增資料會穿透泛型限定

Collection<Stirng> c = new Vector(); //為了相容之前的版本
Collection c = new Vector<String>();

在建立陣列例項時,陣列元素不能使用引數化的型別。
例: Vector<Integer>vectorList[] = new Vector<Integer>[10];
*/

/*26-40
throw 可以 throw T型別
但是 catch 不能 catch T型別
*/

/*26-41
copy1(new Vector<String>(),new String[10];	//傳播性,在型別引數中指明是Data,T就是Data
copy2(new Date[10],new String[10]);	//型別推斷, 型別推斷首先考慮返回值的型別。

public static <T> void copy1(Collection<T> dest, T[] src){}
public static <T> void copy2(T[] dest, T[] src){};
*/

/*26-42
靜態方法不能使用 定義在類上的泛型型別,因為泛型在建立物件時才確定其他具體的型別。

靜態方法可以使用定義在方法上的泛型型別
*/

/*26-43
獲得引數化型別的方法:

Method applyMethod = GenericTest.class.getMethod("applyVector",Vector.class);
Type[] types = applyMethod.getGenericParameterTypes();
Parameterized pType = (ParameterizedType)types[0];
sop(pType.getRawType());
sop(pType.getActualTypeArguments()[0]);
*/

/*26-44
類載入器:JVM預設有BootStrap,ExtClassLoader,AppClassLoader

BootStrap-->jre/lib/rt.jar
	|
ExtClassLoader-->jre/lib/ext/*.jar
	|
AppClassLoader-->classpath指定的所有jar或目錄。

類載入器委託機制:當前的類載入器會先委託個父類,一直到BootStrap類,若父類找到要載入的類就載入該類,子類就不載入,若父類沒有找到,則退回給子類載入,直到發起委託的類。若發起委託的類也沒有找到,則丟擲異常。

System 類是由BootStrap 載入的,因此通常情況下,自己寫一個System類不會被虛擬機器載入。但是可以自己寫類載入器去載入自己寫的類。
*/

/*26-45
 模板方法設計模式:


僅複寫findClass,不用複寫loadClass
 類載入器的原理:
	public Class findClass(String name){
		byte[] b = loadClassData(name);
		return defineClass(name,b,0,b.length);//把二進位制陣列轉變成類位元組碼。
	}
*/

/*26-46

自定義類載入器
	protected Class<?> findClass(String name){
		String classFileName = classDir +"\\" +name +".class";
		try {
			FileInputStream fis = new FileInputStream(classFileName);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			cypher(fis,bos);
			fis.close();
			byte[] bytes = bos.toByteArray();
			return defineClass(bytes,0,bytes.length);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		
		return super.findClass(name);
	}
*/


/*26-48
如果A用到了B,B就由A的載入器去載入

注意extends 是 子類的類載入器與父類的類載入器的關係。
*/

/*26-49
代理可以用來除錯程式的執行時間

如果目標類沒有實現介面,則可以使用CGLib庫 來動態生成代理

代理的方法可以在目標方法的 前,後,及catch塊中 增加程式碼

*/

//26-50_54
package cn.itcast.day3;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

public class ProxyTest {

	/**
	 * @param args
	 * @throws SecurityException 
	 * @throws NoSuchMethodException 
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static void main(String[] args) throws NoSuchMethodException, 
	SecurityException, InstantiationException, IllegalAccessException, 
	IllegalArgumentException, InvocationTargetException {
		// TODO Auto-generated method stub

		Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
		System.out.println(clazz.getName());
		
		System.out.println("begin constructors______________________");
		Constructor[] cons = clazz.getConstructors();
		for(Constructor con : cons){
			String name = con.getName();
			System.out.println("con = " + con);
			System.out.println("conName = " +name);
			
			StringBuilder sb = new StringBuilder(name);
			sb.append("(");
			Class[] clazzParams = con.getParameterTypes();
			for(Class clazzParam : clazzParams){
				sb.append(clazzParam.getName()).append(",");
			}
			
			if(clazzParams != null && clazzParams.length !=0)
				sb.deleteCharAt(sb.length()-1);
			sb.append(")");
			System.out.println(sb);
		}
		
		
		System.out.println("begin methods______________________");
		Method[] methods = clazz.getMethods();
		for(Method method : methods){
			String name = method.getName();
			//System.out.println("method = " + method);
			System.out.println("methodName = " +name);
			
			/*StringBuilder sb = new StringBuilder(name);
			sb.append("(");
			Class[] clazzParams = method.getParameterTypes();
			for(Class clazzParam : clazzParams){
				sb.append(clazzParam.getName()).append(",");
			}
			
			if(clazzParams.length !=0)
				sb.deleteCharAt(sb.length()-1);
			sb.append(")");
			System.out.println(sb);*/
		}
		
		System.out.println("begin instance______________________");
		Constructor<Collection> con = clazz.getConstructor(InvocationHandler.class);
		Collection coll = con.newInstance(new InvocationHandler(){
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				return null;
			}
			
		});
		
		coll.clear();
		//coll.size();//會出錯,因為 proxy返回的null 與 size需求的返回的int 不相符。
		
		
		System.out.println("begin instance______________________");
		Collection collProxy = (Collection) Proxy.newProxyInstance(
				Collection.class.getClassLoader(), 
				new Class[]{Collection.class}, 
				new InvocationHandler() {
					Collection collTarget = new ArrayList();
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						// TODO Auto-generated method stub
						long start = System.currentTimeMillis();
						
						Object retVal = method.invoke(collTarget, args);
						long end = System.currentTimeMillis();
						System.out.println("time cost: " + (end - start));
						return retVal;
					}
				});
		
		collProxy.add("this");
		collProxy.add("is");
		collProxy.add("proxy");
		System.out.println(collProxy.size());
		collProxy.clear();
		
		System.out.println("begin instance of framework______________________");
		final Collection collTarget = new ArrayList();
		Collection collProxy1 = (Collection) gerProxy(collTarget,new MyAdvice());
	}

	private static Object gerProxy(final Object target,final Advice advice) {
		Object proxy = Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
				new Class[]{target.getClass()}, 
				new InvocationHandler() {
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						
						//long start = System.currentTimeMillis();
						advice.beforeMethod(method);
						
						Object retVal = method.invoke(target, args);
						
						advice.afterMethod(method);
						//long end = System.currentTimeMillis();
						
						return retVal;
					}
				});
		return proxy;
	}

}

class MyAdvice implements Advice{

	@Override
	public void beforeMethod(Method m) {
		// TODO Auto-generated method stub
		long start = System.currentTimeMillis();
	}

	@Override
	public void afterMethod(Method m) {
		// TODO Auto-generated method stub
		long end = System.currentTimeMillis();
		System.out.println("time cost: " + (end - start));
	}
	
}

//Advice
package cn.itcast.day3;

import java.lang.reflect.Method;

public interface Advice {

	long start = 0;
	public void beforeMethod(Method m);
	public void afterMethod(Method m);
	
}

//26-56

package cn.heima.aopframework;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import cn.itcast.day3.Advice;

public class BeanFactory {

	Properties prop = new Properties();
	
	public BeanFactory(InputStream ips){
		try {
			prop.load(ips);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public Object getBean(String name){
		String className = prop.getProperty(name);
		Object bean = null;
		try {
			Class clazz = Class.forName(className);
			bean = clazz.newInstance();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
		if (bean instanceof ProxyFactoryBean) {
			Object proxy = null;
			try {
				ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean)bean;
				Advice advice = (Advice)Class.forName(prop.getProperty(name+".advice")).newInstance();
				Object target = Class.forName(prop.getProperty(name+ ".target")).newInstance();
				proxyFactoryBean.setAdvice(advice);
				proxyFactoryBean.setTarget(target);
				proxy = proxyFactoryBean.getProxy();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} 
			return proxy;
		} else {

		}
		return bean;
	}
}


package cn.heima.aopframework;

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

import cn.itcast.day3.Advice;

public class ProxyFactoryBean {
	private Advice advice;
	private Object target;

	public Advice getAdvice() {
		return advice;
	}
	public void setAdvice(Advice advice) {
		this.advice = advice;
	}
	public Object getTarget() {
		return target;
	}
	public void setTarget(Object target) {
		this.target = target;
	}
	
	public Object getProxy(){
		Object proxy = Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
				new Class[]{target.getClass()}, 
				new InvocationHandler() {
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						
						//long start = System.currentTimeMillis();
						advice.beforeMethod(method);
						
						Object retVal = method.invoke(target, args);
						
						advice.afterMethod(method);
						//long end = System.currentTimeMillis();
						
						return retVal;
					}
				});
		return proxy;	
	}
}


package cn.heima.aopframework;

import java.io.InputStream;

public class ProxyTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		InputStream ips = ProxyTest.class.getResourceAsStream(config.prop);
		Object bean = new BeanFactory(ips).getBean("xxx");
		System.out.println(bean.getClass().getName());
	}

}


---------------------- ASP.Net+Android+IO開發S.Net培訓、期待與您交流! ----------------------