`

java 基础加强

    博客分类:
  • J2SE
阅读更多
java基础

jdk1.5  新特征
1。静态导入
   它实现将类中的静态方法导入文件中,例如import static java.lang.Math.*;
2。可变参数(一个方法接受的参数个数不固定)
   只能出现在参数列表的最后;
   ...位于变量类型的变量名之间,前后有无空格都可以;
   调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。
   int... is它类似 int[] is,使用时可以数组的形式访问
3。增强for循环
   for(type 变量名:集合变量){...}
   迭代变量必须在()中定义
   集合变量可以是数组或者实现了Iterable接口的集合类
4。基本数据类型的自动拆箱与装箱
   自动装箱:Integer num =1;  (多个装箱只能转换一个字节-128~127转换成同一个int类型对象,即享元模式:多个对象共享)
   自动拆箱:System.out.println(num + 10);
5。枚举(enum)
   枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错,枚举
   可以让编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目录。
   a.枚举就相当于一个类,其中也可以定义构造方法,成员变量,普通方法和抽象方法。
   b.枚举元素必须位于枚举体中的最开始部分,枚举元素列表后要有分号与其它成员变量分隔。
   c.带构造方法的枚举:构造方法必须定义成私有的,如果多个构造方法,默认是空构造方法();
   d.带方法的枚举:每个元素分别由枚举的子类来生成的实例对象,这些子类采用类似内部类的方式进行定义
   f.枚举只有一个成员时,就可以作为一种单例的实现方式
   实例:
package cn.com;

public class EnumTest {
    public static void main(String args[]){
    	WeekDay wd = WeekDay.MON;
    	System.out.println(wd);
    	System.out.println(wd.name());
    	System.out.println(wd.ordinal());
    	System.out.println(wd.valueOf("SAT").toString());
    	System.out.println(wd.values().length);
    	TrafficLamp tr =TrafficLamp.RED;
    	System.out.println(tr.nextLamp()); 	
    }
    
    public enum WeekDay{
    	SUM,MON(),TUS(0),WED(1),THI,FRI,SAT;
    	private WeekDay(){
    		System.out.println("first");
    	}
    	private WeekDay(int day){
    		System.out.println("second");
    	}
    }
    
    public enum TrafficLamp{
    	RED(30){
			public TrafficLamp nextLamp() {
				return GREEN;
			}
    		
    	},
    	GREEN(10){
			public TrafficLamp nextLamp() {
				return YELLOW;
			}
    		
    	},
    	YELLOW(30){
			public TrafficLamp nextLamp() {
				return RED;
			}
    		
    	};
    	
    	public abstract TrafficLamp nextLamp();
    	private int time;
    	private TrafficLamp(int time){
    		this.time = time;
    	}
    }
}

反射 (jdk 1.2后具有的特性)
反射的基石-》classs 类
1.java程序中的各个java类属于同一个类事物,描述这类名就是Class.
2.获取字节码的方式:
   类名class,例如:System.class
   对象.getClass(),例如:new Date().getClass();
   Class.forName("类名"),例如:ClassName.forname("java.util.Date");
反射就是把java类中的各种成分映射成相应的java类。
Constructor类
getConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法,newInstance() 创建此 Class 对象所表示的类的一个新实例
Field类
Field类代表某个类中的一个成员变量
Method类
Method类代表某个类中的一个成员方法
invoke(null,Class<?>);如果参数是null表示一个静态方法
Arrays.asList(Object);将数组对象转换成Array
演示例如:
package cn.com;

public class ReflectPoint {
   private int x;
   public int y;
   public String str1 = "ball";
   public String str2 = "babbling";
   public String str3 = "China";

   public ReflectPoint(int x, int y) {
	this.x = x;
	this.y = y;
  }

@Override
public String toString() {
	return "str1="+str1+" str2="+str2+" str3="+str3;
} 
}

package cn.com;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;

public class ReflectTest {
   public static void main(String arg[]) throws Exception{
	   String str1 = "abc";
	   Class<? extends String> cls1 = str1.getClass();
	   Class<String> cls2 = String.class;
	   Class<?> cls3 = Class.forName("java.lang.String");
	   System.out.println(cls1 == cls2);
	   System.out.println(cls1 == cls3);
	   
	   System.out.println(cls1.isPrimitive());  //是否是一个基本类型
	   System.out.println(int.class.isPrimitive());
	   System.out.println(int.class == Integer.class);
	   System.out.println(int.class == Integer.TYPE);
	   System.out.println(int[].class.isPrimitive());
	   System.out.println(int[].class.isArray());
	   
	   Constructor<String> cons = String.class.getConstructor(StringBuffer.class);
	   String str2 = (String)cons.newInstance(new StringBuffer("abc"));
	   System.out.println(str2);
	   System.out.println(str2.charAt(2));
	   
	   ReflectPoint p1 = new ReflectPoint(2,4);
	   Field y = p1.getClass().getField("y");
	   System.out.println(y.get(p1));
	   Field x = p1.getClass().getDeclaredField("x");
	   x.setAccessible(true);
	   System.out.println(x.get(p1));
	   
	   changeStringValue(p1);
	   System.out.println(p1);
	   
	   //str1.charAt(1);
	   Method methodCharAt = String.class.getMethod("charAt", int.class);
	   System.out.println(methodCharAt.invoke(str1, 1));
	   System.out.println(methodCharAt.invoke(str1, new Object[]{0}));
	   
	   String starting = arg[0];
	   Method mainMethod = Class.forName(starting).getMethod("main", String[].class);
	   mainMethod.invoke(null, new Object[]{new String[]{"abc","bcd"}});
	   
	   int[] a1 = new int[]{1,2,3};
	   int[] a2 = new int[4];
	   int[][] a3 = new int[2][3];
	   String[] a4 = new String[]{"abc","bcd","efg"};
	   System.out.println(a1.getClass() == a2.getClass());
	   System.out.println(a1.getClass().getName());
	   System.out.println(a1.getClass().getSuperclass().getName());
	   
	   Object object1 =  a1;
	   Object object2 = a2;
	   Object object3[] = a3;
	   Object object4[] = a4;
	  // Object object5[] = a1;
	   System.out.println(object1+" "+object2+" "+object3+" "+object4);
       System.out.println(Arrays.asList(a1));
       System.out.println(Arrays.asList(a4));
       
       printObject(a1);
       printObject(a4);
   }

private static void printObject(Object obj) {
	if(obj.getClass().isArray()){
		for(int i=0;i<Array.getLength(obj);i++){
			System.out.println(Array.get(obj, i));
		}
	}
}

private static void changeStringValue(Object p1) throws IllegalArgumentException, IllegalAccessException {
   Field[] fields = p1.getClass().getFields();
   for(Field field : fields){
	   if(field.getType() == String.class){
	   String oldValue = (String) field.get(p1);
	   String newValue = oldValue.replace('b', 'a');
	   field.set(p1, newValue);
	   }
   }
}
}

class TestMain{
	public static void main(String args[]){
		for(String str : args){
			System.out.println(str);
		}
	}
}

2.集合类
HashSet储存时要hashCode、equals比较,保证储存的值不相同
当一个对象被存储进Hashset集合中以后,就不能修改这个对象中的那些参与
计算哈希值的字段了,否则对象修改后的哈希值与最初存储存HashSet集合中时哈希值
就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去
HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet
集合中单独删除当前的对象,从而造成内在泄露。
反射的作用-》实现框架功能
框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。
演示例如:
package cn.com;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Properties;

public class ReflectTest1 {
   public static void main(String arg[]) throws Exception{
     Collection collections = new ArrayList();
     ReflectPoint rp1 = new ReflectPoint(3,3);
     ReflectPoint rp2 = new ReflectPoint(5,5);
     ReflectPoint rp3 = new ReflectPoint(3,3);    
     collections.add(rp1);
     collections.add(rp2);
     collections.add(rp3);
     collections.add(rp1);
     System.out.println(collections.size());
     
//     InputStream in = new FileInputStream("config.properties");
//     InputStream in = ReflectTest1.class.getClassLoader().getResourceAsStream("..\\config.properties");//类加载器
     InputStream in = ReflectTest1.class.getResourceAsStream("..\\..\\..\\config.properties");
     Properties proper = new Properties();
     proper.load(in);
     in.close();
     String className = proper.getProperty("className");
     collections = (Collection) Class.forName(className).newInstance();
//     collections = new HashSet(); //hashCode、equals比较,保证储存的值不相同
     collections.add(rp1);
     collections.add(rp2);
     collections.add(rp3);
     collections.add(rp1);
     System.out.println(collections.size());
      rp1.y = 10;
     collections.remove(rp1);
     System.out.println(collections.size());
     
   }

}

由内省引出JavaBean
JavaBean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合命名规则。
package cn.com;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;

public class IntroSpectorTest {

	public static void main(String[] args) throws Exception {
		ReflectPoint pion = new ReflectPoint(3, 4);
		
		String properyName = "x";
		Object obj = getProperty(pion, properyName);
		System.out.println(obj);
		
		Object value =5;
		setProperty(pion, properyName, value);
		System.out.println(pion.getX());
		
		System.out.println(BeanUtils.getProperty(pion, "x"));
		BeanUtils.setProperty(pion,"x","8");
		System.out.println(pion.getX());
		BeanUtils.setProperty(pion,"brith.time","1000");
	    System.out.println(BeanUtils.getProperty(pion, "brith"));
		PropertyUtils.setProperty(pion, "x", 10);
		System.out.println(PropertyUtils.getProperty(pion, "x"));
	}

	private static void setProperty(Object pion, String properyName,
			Object value) throws IntrospectionException,
			IllegalAccessException, InvocationTargetException {
		PropertyDescriptor pd2 = new PropertyDescriptor(properyName, pion.getClass());
		Method setX = pd2.getWriteMethod();
		setX.invoke(pion, value);
	}

	private static Object getProperty(Object pion, String properyName)
			throws IntrospectionException, IllegalAccessException,
			InvocationTargetException {
		/*PropertyDescriptor pd = new PropertyDescriptor(properyName, pion.getClass());
		Method getX = pd.getReadMethod();
		Object obj = getX.invoke(pion);*/
		BeanInfo bean =Introspector.getBeanInfo(pion.getClass());
		PropertyDescriptor[] pds = bean.getPropertyDescriptors();
		Object obj = null;
		for(PropertyDescriptor ps : pds){
			if(ps.getName().equals(properyName)){
				Method getX = ps.getReadMethod();
				 obj = getX.invoke(pion);
			}
		}
		return obj;
	}

}

注解 (jd1.5新特征)
注解相当一种标记,java编译器,开发工具和其它程序可以用来反射标记,标记可以在包,类,字段,方法参数以及局部变量上。
Deprecated          //过期
Override            //重写覆盖
SuppressWarnings    //取消显示指定的编译器警告(@SuppressWarnings("deprecation"))
@Retention(RetentionPolicy.RUNTIME)   //保存在运行时(CLASS 保留策略默认,SOURCE 编译器要丢弃的注释)
@Target(ElementType.METHOD)    //限制在方法声明使用 {ElementType.METHOD,ElementType.TYPE} TYPE(包括Class Interface Enum等)
package cn.com;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface Annotation {
   String color() default "blue"; //= public abstract String color();
   String value(); //value是个特殊的关键字,当只有value一个参数时,应用时可以不写value
   int[] arrayAttr() default {2,3,4};
   ElementType elem() default ElementType.TYPE; 
   MetaAnnotation metaAnnotation() default @MetaAnnotation("abc");
   Class classes() default StringBuffer.class;
}

package cn.com;

@Annotation(classes=String.class,metaAnnotation=@MetaAnnotation("bgf"),color="red",value="abc",arrayAttr=2)//={1,2,3}
public class AnnotationTest {

	@SuppressWarnings("deprecation")
	@Annotation("xyz")
	public static void main(String[] args) {
      System.runFinalizersOnExit(true);
      new AnnotationTest().hello();
      
      if(AnnotationTest.class.isAnnotationPresent(Annotation.class)){
    	  Annotation annotation = AnnotationTest.class.getAnnotation(Annotation.class);
    	  System.out.println(annotation);
    	  System.out.println(annotation.color());
    	  System.out.println(annotation.value());
    	  System.out.println(annotation.arrayAttr());
    	  System.out.println(annotation.elem());
    	  System.out.println(annotation.metaAnnotation().value());
    	  System.out.println(annotation.classes());
      }
	}
    @Deprecated
	public void hello(){
		System.out.println("你好!");
	}
    
}

泛型(jd1.5新特征)
泛型是提供java编译器使用的,可以限定集合中的输入类型,使程序运行效果不受影响。
AarryList<E>类定义和ArraryList<Integer>类引用中涉及如下术语:
整个称为ArrayList<E>泛型类型
整个ArraryList<Integer>称为参数化的类型
ArraryList<Interge>中的Interge称为类型参数的实例或实际类型参数
ArraryList<Interge>中的<>  typeof
ArraryList称为原始类型
参数化类型与原始类型的兼容性:
参数化类型可以引用一个原始类型的对象,编译报警告
原始类型可以引用一个参数化类型的对象,编译报警告
参数化类型不考虑参数的继承关系
在创建数组实例时,数组的元素不能使用参数化的类型,如下
Vector<Integer> verctor[] = new Vector<Integer>[10];//错误写法
使用?通配符可以用其它各种参数化的类型,?通配符定义的变量主要作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
限定通配符的上下边界:
限定通配符的上边界:如 Vector<? extends Number> x = new Vector<Integer>();
限定通配符的下边界:如 Vector<? super Interger> x = new Vector<Number>();
提示:限定通配符总是包括自己
泛型中的T代表任意类型。
只有引用类型才有泛型方法的实际参数,基本类型是没有泛型的。
除了在应用时以使用extends限定符,在定义泛型时也可以使用extends限定符,并且可以指定多个边界
普通方法,构造方法和静态方法中都可以使用泛型,编译器也不允许创建类型变量的数组
也可以用类型变量表示异常,称为参数化的异常,可以可以用于方法的throws列表中,但是不能用于catch子句中
在泛型中可以同时有多个类型参数,在定义它们的尖括号中用逗号分开
?通配符比泛型T任意类型更有效
类型推断
1、只有一处调用一个类型,或者多处调用同一个类型,推断出是当时这个类型
2、如果多处使用不同对象,并且没有返回值,取他们的交集
3、如果有返回值,优先考虑有返回值的类型
4、类型具有传递性
5、静态方法不能类泛型,要独立开单独类型
package cn.com;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

public class GanericTest {

	public static void main(String[] args) throws Exception {
       ArrayList<String> list = new ArrayList<String>();
       list.add("abc");
       
       ArrayList<Integer> list1 = new ArrayList<Integer>();
       list1.add(1);
       System.out.println(list.getClass() == list1.getClass());
       
      list1.getClass().getMethod("add", Object.class).invoke(list1, "xyz");
      System.out.println(list1.get(1));
      
      printConllection(list);
      printConllection(list1);
      
      Class<? super String> str = String.class.getSuperclass();
      System.out.println(str);
      
      Map<String,Integer> map = new HashMap<String, Integer>();
      map.put("张三", 20);
      map.put("李四", 21);
      map.put("王五", 22);
      
      Set<Map.Entry<String,Integer>> set =map.entrySet();
      for(Map.Entry<String,Integer> entry : set){
    	  System.out.println("key = "+entry.getKey()+"   value = "+entry.getValue());
      }
      
      add(3,5);
      Number x1 = add(3.5,3);
      Object x2 = add(3,"abc");
      
      swap(new String[]{"abc","def","ghi"},1,2);
      
      Object obj ="abc";
      String x3 = autoConvert(obj);
      
      copy1(new Vector<String>(),new String[10]);
      copy2(new Date[10], new String[10]);
      //copy1(new Vector<Date>(),new String[10]);
      
      //Vector v1 = new Vector<Date>();
      Method applyMethod = GanericTest.class.getMethod("applyVector", Vector.class);
      Type[] types = applyMethod.getGenericParameterTypes();
      ParameterizedType ptype = (ParameterizedType) types[0];
      System.out.println(ptype.getRawType());
      System.out.println(ptype.getActualTypeArguments()[0]);
	}

	private static <T> T autoConvert(Object obj) {
		return (T)obj;
	}
    
	private <T> void fillArrary(T[] a,T obj){
		for(T t : a){
			t = obj;
		}
	}
	private static <T> void swap(T[] a, int i, int j) {
        T temp = a[i];
        a[i] = a[j];
        a[j] =temp;
	}

	private static <T>T add(T i, T j) {
		return j;	
	}

	private static void printConllection(ArrayList<?> list) {
		for(Object obj : list){
			System.out.println(obj);
		}
	}
	
	private static <T> void  printConllection2(ArrayList<T> list) {
		for(Object obj : list){
			System.out.println(obj);
		}
	}
    
	private static <T> void copy1(Collection<T> dest,T[] src){
	for(T a : src){
		dest.add(a);
	}
	}
	
	private static <T> void copy2(T[] dest, T[] src){
	  for(int i=0; i<src.length; i++){
		 dest[i] = src[i]; 
	  }
	}
	public static void applyVector(Vector<Date> v){
		
	}
}


类加载器
java虚拟机安装多个类加载器,系统默认三个主要类加载器,每个类负载加载特定位置的类: BootStrap,ExtClassLoader,AppClassLoader
类加载器也是java类,因为其他是java类的类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是java类,这个是BootStrap
java虚拟机中的所有类装载器采用具有父子关系的树形结构进行组织,在实例化每个类装载器对象,需要为其指定一个父级装载器对象或者默认采用系统类装载器为其父级类加载
类加载器之间的父子关系和管辖范围
BootStrap<-ExtClassLoader<-AppClassLoader
BootStrap->JRE/lib/rt.jar
ExtClassLoader->JRE/lib/ext/*.jar
AppClassLoader(System classLoader)->ClASSPATH指定的所有jar或目录
类加载器的委托(子类交给父类)
package cn.com;

import java.util.Date;

public class ClassLoaderAttachment extends Date{

	@Override
	public String toString() {
		return "hello ClassLoaderAttachment";
	}

}
package cn.com;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class MyClassLoader extends ClassLoader {
	private String classDir;
	public MyClassLoader(){
		
	}
    public MyClassLoader(String classDir){
		this.classDir = classDir;
	}
    public static void main(String args[]) throws Exception{
    	String srcPath = args[0];
    	String destDir = args[1];
    	FileInputStream fis = new FileInputStream(srcPath);
    	destDir +="\\"+srcPath.substring(srcPath.lastIndexOf("\\")+1);
    	FileOutputStream fos = new FileOutputStream(destDir);
    	cypher(fis, fos);
    	fis.close();
    	fos.close();
    }

    private static void cypher(InputStream ips, OutputStream ops) throws IOException{
    	int b = -1;
    	while((b = ips.read())!= -1){
    		ops.write(b ^ 0xff);
    	}
    }
    
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		String classPath = classDir + "\\" +name.substring(name.lastIndexOf(".")+1)+".class";
		try {
			FileInputStream fis = new FileInputStream(classPath);
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			cypher(fis, bout);
			fis.close();
			byte[] bytes = bout.toByteArray();
			return defineClass(bytes, 0, bytes.length);  //生成字节数组
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (ClassFormatError e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return super.findClass(name);
	}
    
}

package cn.com;

import java.util.Date;

public class ClassLoaderTest {

	public static <ClassLoaderAttachment> void main(String[] args) throws Exception {
      System.out.println(ClassLoaderTest.class.getClassLoader().getClass().getName());
      ClassLoader loader = ClassLoaderTest.class.getClassLoader();
      while(loader != null){
    	  System.out.println(loader.getClass().getName());
    	  loader = loader.getParent();
      }
      System.out.println(loader);
      //System.out.println(new ClassLoaderAttachment());
      
      Class clazz = new MyClassLoader("Loader").loadClass("cn.com.ClassLoaderAttachment");
      Date d1 =  (Date) clazz.newInstance();
      System.out.println(d1);
	}
}


代理
要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如:异常、日志、计算方法的运用时间,事物等。
采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类还是代理类。
AOP
交叉业务的编程问题即为面向方面的编程(AOP)
AOP目标就是要使交叉业务模块化,可以采用将切换面代码移动到原始方法的周围,这与直接在方法中编写切面代码的运行效果是一样的。
动态代理技术
JVM可以在运行时动态生出类的字节码,这种动态生成的类往往被称作代理类,即动态代理类。
JVM生成的动态类必须实现一个或者多个接口,所以,JVM生成的动态类只能用作具有相同接口的目标类的代理。
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,可以使用CGLIB库。
代理类的各种方法中通常除了要调用目标相应方法和对外返回的结果外,还可以在代理方法中加上系统功能代码。
调用代理对象时,从Object类中继承hashCode,equals,或toString这几个方法,代理对象将调用请求转发给
InvocationHanderler对象,对于其他方法,则不转发调用请求。
package cn.com;

import java.lang.reflect.Method;

public interface Advice {
    void beforeMethod();
    void afterMethod(Method method);
}

package cn.com;

import java.lang.reflect.Method;

public class MyAdvice implements Advice {
	long starttime = 0;
	@Override
	public void beforeMethod() {
		 starttime = System.currentTimeMillis();
	}

	@Override
	public void afterMethod(Method method) {
		long endtime = System.currentTimeMillis();
		System.out.println(method + " 发费时间:" + (endtime - starttime));
	}

}

package cn.com;

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

public class ProxyTest {
     public static void main(String args[]) throws Exception{
    	 Class clazzProxy = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
    	 System.out.println(clazzProxy.getName());
    	 System.out.println("-----begin constuctor------");
    	 Constructor[] constraints = clazzProxy.getConstructors();
    	 for(Constructor constructor : constraints){
    		 String name = constructor.getName();
    		 StringBuffer sBuffer = new StringBuffer(name);
    		 sBuffer.append("(");
    		 Class[] classParams = constructor.getParameterTypes();
    		 for(Class classparam : classParams){
    			 sBuffer.append(classparam.getName()+" "+
    					 classparam.getName().substring(classparam.getName().lastIndexOf(".")+1,
    							 classparam.getName().length()).toString().toLowerCase()).append(',');
    		 }
    		 if(classParams.length>0){
    			 sBuffer.deleteCharAt(sBuffer.length()-1);
    		 }
    		 sBuffer.append(")");
    		 System.out.println(sBuffer);
    	 }
    	 System.out.println("-----begin method------");

    	 Method[] methods = clazzProxy.getMethods();
    	 for(Method method : methods){
    		 String name = method.getName();
    		 StringBuffer sBuffer = new StringBuffer(name);
    		 sBuffer.append("(");
    		 Class[] classParams = method.getParameterTypes();
    		 for(Class classparam : classParams){
    			 sBuffer.append(classparam.getName()+" "+
    					 classparam.getName().substring(classparam.getName().lastIndexOf(".")+1,
    							 classparam.getName().length()).toString().toLowerCase()).append(',');
    		 }
    		 if(classParams.length>0){
    			 sBuffer.deleteCharAt(sBuffer.length()-1);
    		 }
    		 sBuffer.append(")");
    		 System.out.println(sBuffer);
    	 }
    	 
    	 System.out.println("-----begin create instance------");
    	 Constructor constructor = clazzProxy.getConstructor(InvocationHandler.class);
          class  MyInvocationHander implements InvocationHandler{
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				return null;
			}
		
         }
         Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHander());
         proxy1.clear();
         Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				return null;
			}	 
         });
         final ArrayList target = new ArrayList();
         Collection proxy3 = (Collection) getProxy(target,new MyAdvice());
         proxy3.add("abc");
         proxy3.add("xyz");
         System.out.println(proxy3.size());
     }

	private static Object getProxy(final Object target,final Advice advice) {
		Object proxy3 =  Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
        		/* new Class[]{Collection.class},*/
				target.getClass().getInterfaces(),
        		 new InvocationHandler(){						    
        				public Object invoke(Object proxy, Method method, Object[] args)
        						throws Throwable {
        					/*long starttime = System.currentTimeMillis();
        					Object retVal = method.invoke(target, args);
        					long endtime = System.currentTimeMillis();
        					System.out.println(method + " 发费时间:" + (endtime - starttime));
        					return retVal;*/
        					
        					advice.beforeMethod();
        					Object retVal = method.invoke(target, args);
        					advice.afterMethod(method);
        					return retVal;
        				}	 
        	         });
		return proxy3;
	}
}

实现AOP功能的封装与配制
工厂类BeanFactory负责创建目标类的实现类或代理类的实例对象,并通过配制文件实现切换。其getBean方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配制文件中对应的类名不是ProxyFactyBean,则返回类的实例圣像,否则,
返回该类的实例对象的getProxy方法返回的对象。
BeanFactory的方法接收代表配制文件的输入流对象。
ProxyFacotryBean充当封装生成动态代理的工厂,需要为工厂类提供目标和通知信息。
编写客户端应用,实现Advice接口类和在配制文件中进行配置,调用BeanFactory获取对象。
package cn.com;

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

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

package cn.com;

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

public class ProxyFactoryBean {
    private Object target;
    private Advice advice;
    
    
	public Object getTarget() {
		return target;
	}


	public void setTarget(Object target) {
		this.target = target;
	}


	public Advice getAdvice() {
		return advice;
	}


	public void setAdvice(Advice advice) {
		this.advice = advice;
	}


	public Object getProxy() {
		Object proxy3 =  Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
        		/* new Class[]{Collection.class},*/
				target.getClass().getInterfaces(),
        		 new InvocationHandler(){						    
        				public Object invoke(Object proxy, Method method, Object[] args)
        						throws Throwable {
        					/*long starttime = System.currentTimeMillis();
        					Object retVal = method.invoke(target, args);
        					long endtime = System.currentTimeMillis();
        					System.out.println(method + " 发费时间:" + (endtime - starttime));
        					return retVal;*/
        					
        					advice.beforeMethod();
        					Object retVal = method.invoke(target, args);
        					advice.afterMethod(method);
        					return retVal;
        				}	 
        	         });
		return proxy3;
	}
}

package cn.com;

import java.io.InputStream;
import java.util.Collection;

public class AopFrameworkTest {

	public static void main(String[] args) {
     InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");
     Object bean = new BeanFactory(ips).getBean("xxx");
     System.out.println(bean.getClass().getName());
     ((Collection)bean).clear();
	}

}
分享到:
评论

相关推荐

    Java基础加强系列视频课程

    资源名称:Java基础加强系列视频课程资源目录:【】黑马程序员Java基础加强(01-10)【】黑马程序员Java基础加强(11-20)【】黑马程序员Java基础加强(21-30)【】黑马程序员Java基础加强(31-40)【】黑马程序员...

    Java基础加强

    "Java基础加强"的课程或学习资源通常旨在帮助初学者巩固和深化对Java基础知识的理解,以便更好地掌握这门语言的核心概念和技术。在这个主题中,我们将探讨几个关键的知识点: 1. **Java语法基础**:包括数据类型...

    张孝祥老师Java基础加强

    【Java基础加强】是编程领域中的一个重要主题,尤其对于初学者和准备面试的开发者来说,扎实的Java基础知识是必备的。张孝祥老师的教程聚焦于提升这些基础技能,旨在帮助学员深入理解Java语言的核心概念,并为应对...

    Java基础加强--张孝祥版.ppt

    Java基础加强--张孝祥版 传智播客

    张孝祥老师Java基础加强(高新技术PPT课件)ppt

    【Java基础加强——高新技术在编程中的应用】 Java作为一款广泛应用的高级编程语言,其基础知识的扎实程度直接影响到程序员的开发效率和代码质量。张孝祥老师的"Java基础加强"课程,旨在通过高新技术PPT课件的形式...

    Java基础加强-个人总结doc

    这份"Java基础加强-个人总结doc"文档,结合了张孝祥老师的PPT,为我们提供了全面而深入的学习材料。以下是这份文档可能涵盖的一些核心知识点: 1. **基础知识**:这部分涵盖了Java语言的基础语法,包括变量、数据...

    张孝祥java基础加强视频教程笔记

    【Java基础加强】张孝祥的Java教学视频涵盖了Java编程语言的基础到进阶知识,旨在帮助学习者巩固和提升Java编程技能。以下是根据教程笔记整理的一些关键知识点: 1. **Java简介**:Java是一种跨平台的面向对象的...

    张孝祥 Java 基础加强 高新技术

    张孝祥 Java_基础加强 高新技术 全部内容 共67页面

    Java基础加强.ppt

    这是很好的Java基础加强ppt,实际例子,值得收藏!

    Java基础加强,成就java高手

    总的来说,这个课程旨在通过深入讲解这些Java基础加强的知识点,帮助学员提升Java编程的水平,从而在实际开发中更加得心应手,迈向高级软件人才的行列。通过学习和实践这些内容,不仅能够巩固基础知识,还能掌握更多...

    01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip

    【标题】"01_黑马程序员_张孝祥_Java基础加强_课程价值与目标介绍.zip" 提供的是一门由黑马程序员机构推出的Java基础强化课程,由讲师张孝祥主讲,旨在深入讲解Java编程的基础知识并进行能力提升。 【描述】中提到...

    年java基础加强.pptx

    Java基础加强是编程学习的重要阶段,它涵盖了众多关键概念,帮助开发者掌握Java语言的基础技能。在2020年的Java基础加强课程中,Eclipse的使用是一个重要部分。Eclipse是一个广泛使用的Java集成开发环境(IDE),...

    传智播客java基础加强班-Java编程基础.ppt

    在传智播客的Java基础加强班中,学生将深入学习Java编程的基础知识,包括但不限于以下几个方面: 1. **Java语法格式**: - Java代码结构基于类,每个程序至少包含一个类,由`class`关键字定义。 - 大小写敏感是...

    张孝祥老师Java基础加强(完整版).ppt

    配套视频: 黑马程序员张孝祥高新技术 https://www.bilibili.com/video/av7717207

    JAVA基础加强源码

    "JAVA基础加强源码"这个主题表明我们正在讨论的是关于Java编程的基础知识,并且通过源码来加深理解。源码是程序员可以直接阅读和修改的程序文本,是学习编程语言最直接的方式。 在Java基础部分,我们通常会涵盖以下...

    Java基础加强_eclipse工程管理与快捷键配置

    本资源“Java基础加强_eclipse工程管理与快捷键配置”旨在帮助初学者和开发者深入理解如何在Eclipse中有效地管理和优化工作环境,特别是针对Java项目的操作以及快捷键的设置。 首先,让我们探讨Eclipse中的工程管理...

    张孝祥Java基础加强视频练习源代码

    【Java基础加强】 在Java编程领域,基础知识的掌握至关重要,因为它是构建复杂应用程序的基石。张孝祥的Java基础加强视频系列旨在帮助初学者和有一定经验的开发者巩固和提升Java编程技能。这个系列涵盖了Java语言的...

    JAVA基础加强

    java基础加强版 ,更人性的巩固基础,万丈高楼平地起,只有打好基础,才能理解更复杂的东西

Global site tag (gtag.js) - Google Analytics