黑马程序员 ---- java基础加强(下)

本文深入探讨JavaBean的内省操作方法,包括属性读写、BeanUtils工具类的使用;同时详述Java泛型的基础概念及其高级应用,如泛型方法、类和参数化类型等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 —————————— ASP.Net+Android+IOS开发.Net培训、期待与您交流!——————————


内省(IntroSpector) 对javaBean操作


如果在两个模块之间传递多个信息,可以将这些信息封装到一个javaBean中,这种javaBean的实例对象通常称为
值对象(Value Objeect);


如果属性的第二个字母为小写,那么第一个字母就是小写 
getCPU --  CPU
getTime--  time
gettime--  time


对javaBean的简单内省操作
PropertiesDescriptor属性描述类


getReadMethod();//get
getWriteMethod();//set


Extract 抽取


复杂的内省操作:
BeanInfo = IntroSpector.getBeanInfo();
在getPropertyDescriptors();
通过getName 在equals属性名



package day2;

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;


//简单的内省操作javaBean  和复杂的内省操作javaBean
public class EasyIntroSpector
{
	public static void main(String[] args)throws Exception
	{
		Person person=new Person("其实我很在乎你",10);
		String propertyName="name";
		String setValue="累了醉了就想哭";
		
		//设置
		setProperty(person, propertyName, setValue);
		
		
		//获取
		getProperty(person, propertyName);
		
		
		
		
	}

	private static void setProperty(Person person, String propertyName, String setValue)
			throws IntrospectionException, IllegalAccessException, InvocationTargetException
	{
		
		//简单的内省操作
/*		
		PropertyDescriptor pDescriptor=new PropertyDescriptor(propertyName, person.getClass());
		Method method=pDescriptor.getWriteMethod();
		method.invoke(person, setValue);
		*/
		
		//复杂的内省操作
		BeanInfo beanInfo= Introspector.getBeanInfo(person.getClass());
		PropertyDescriptor[] pDescriptors = beanInfo.getPropertyDescriptors();
		for (PropertyDescriptor propertyDescriptor : pDescriptors)
		{
			if(propertyDescriptor.getName().equals(propertyName))
			{
				Method method=propertyDescriptor.getWriteMethod();
				method.invoke(person, setValue);
			}
		}
	}

	private static void getProperty(Person person, String propertyName)
			throws IntrospectionException, IllegalAccessException, InvocationTargetException
	{
		//简单的内省操作
		
		/*PropertyDescriptor pdDescriptor=new PropertyDescriptor(propertyName, person.getClass());
		
		Method method=pdDescriptor.getReadMethod();
		System.out.println(method.invoke(person));*/
		
		//复杂的内省操作
		
		BeanInfo beanInfo=Introspector.getBeanInfo(person.getClass());
		
		PropertyDescriptor[] propertyDescriptors=beanInfo.getPropertyDescriptors();
		
		for (PropertyDescriptor propertyDescriptor : propertyDescriptors)
		{
			if(propertyDescriptor.getName().equals(propertyName))
			{
				Method method=propertyDescriptor.getReadMethod();
				System.out.println(method.invoke(person));
			}
		}
	}
}



使用BeanUtils工具类操作Bean
getProperty();
setProperty();


例如Date  符合属性  属性可以级联




PropertiesUtils操作Bean


BeanUtils与PropertiesUtils区别
1.BeanUtils可以使用字符串内部会自动转换,而PropertiesUtils只能使用本身的属性类型


package day2;

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

//使用BeanUtils工具包操作 javaBean
public class BeanUtilsTest
{
	public static void main(String[] args)throws Exception
	{
		
		//BeanUtils与PropertyUtils的区别
		//前者可以传入字符串,内部会自动转换,  后者只能传自身属性的类型,因为内部不会有转换
		
		
		Person person=new Person("关不上的窗",15);
		String propertyName="name";
		String setValue="我的故乡黑龙江";
		
		BeanUtils.setProperty(person, propertyName, setValue);
		
		String name=BeanUtils.getProperty(person, propertyName);
		
		System.out.println(name);
		
		String proString="age";
		
		//不能传入字符串 内部不会自动转换  自己传自身的类型
		//PropertyUtils.setProperty(person, proString, "15");
		PropertyUtils.setProperty(person, proString, 60);
		
		int age = (int)PropertyUtils.getProperty(person,proString);
		
		System.out.println(age);
		
		
		//Date级联 属性
		
		System.out.println(BeanUtils.getProperty(person, "date.time"));
		
	}
}



几个基本注解(Annotation)
1.@SuppressWarnings(); //传入的是数组,当只有一个值可以直接传入 {"unused","unchecked","deprecation","rawtypes"}
2.@Deprecated  //过时的
@Override //重写   


一个注解就是一个类


注解相当与一种标记,加了注解就等于打上了某种标记,没加就等于没有这种标记,以后javac编译器,开发工具和其他程序
就可以用反射来了解你的类及各种元素上有无何何种标记,告诉你有什么标记,就去干相应的事


标记可以加在包中,构造方法,普通方法,类,局部变量,成员变量上..


package day2;
//注解的入门  
public class AnnotationTest
{
	@SuppressWarnings("deprecation")//压缩警告,过时方法不警告
	public static void main(String[] args)
	{
		
		show();
		System.runFinalizersOnExit(false);
		
		
	}
	@Deprecated //标志为已过时方法
	public static void show()
	{
		System.out.println("show方法");
	}
	
	@Override //加上注解如果复写方法不对 会编译错误
	public String toString()
	{
		return AnnotationTest.class.getName();
	}
}



注解类的应用结构


1.注解类 @interface
2.应用了注解的类
3.对应用了注解的类进行反射操作


isAnnotationPresent(注解类.class); 




@Retent(RetentionPolicy.RUNTIME) 保留运行期间
RetentionPolicy.SOURCE  保留在源文件上
RetentionPolicy.CLASS   保留在class字节码文件上


@Target({ElementType.METHOD})  注解可以存放位置例如方法METHOD,类TYPE
ElementType.METHOD
ElementType.FIELD
ElementType.LOCAL_VARIABLE
ElementType.TYPE
ElementType.PARAMTER
ElementType.CONSTRUCTOR
ElementType.PACKAGE
ElementType.ANNOTATION_TYPE


为注解类添加基本属性
String 
int[]
只有一个设置值时,可以直接传入


可以设置默认值 加上default关键字即可


为注解添加高级属性,  枚举,注解类,Class等


package day2;
//注解的入门  
public class AnnotationTest
{
	@SuppressWarnings("deprecation")//压缩警告,过时方法不警告
	public static void main(String[] args)
	{
		
		show();
		System.runFinalizersOnExit(false);
		
		
	}
	@Deprecated //标志为已过时方法
	public static void show()
	{
		System.out.println("show方法");
	}
	
	@Override //加上注解如果复写方法不对 会编译错误
	public String toString()
	{
		return AnnotationTest.class.getName();
	}
}


package day2;

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.TYPE)
public @interface Itcast
{
	int value(); //当方法名为Value  只有一个参数可以 直接注解类(值)
}



package day2;

import java.lang.reflect.Method;
import java.nio.file.AccessMode;
import java.util.Arrays;

import day1.EnumTest3.Lamp;


//注解的高级应用
@AnnotationClass(getName = "类上")
public class AnnatationTest1
{
	@SuppressWarnings("rawtypes")
	@AnnotationClass(getName="方法上")
	public static void main(String[] args)throws Exception
	{
		if(AnnatationTest1.class.isAnnotationPresent(AnnotationClass.class))
		{
			//注解类
			AnnotationClass aClass=AnnatationTest1.class.getAnnotation(AnnotationClass.class);
			System.out.println(Arrays.toString(aClass.getArr()));
			
			System.out.println(aClass.getClass().getName());
			System.out.println(aClass.getClass().getSuperclass().getName());
			
		
			Itcast itcast=aClass.getItcast();
			System.out.println(itcast.getClass().getName());
			System.out.println("value值是:"+itcast.value());
			
			Lamp lamp=aClass.getLamp();
			System.out.println(lamp);
			System.out.println(lamp.nextLamp());
			
			Class clazz=aClass.getClassName();
			System.out.println(clazz.getName());
			
		}
		
		Method method = AnnatationTest1.class.getMethod("main", String[].class);
		
		if(method.isAnnotationPresent(AnnotationClass.class))
		 {
			AnnotationClass aClass=AnnatationTest1.class.getAnnotation(AnnotationClass.class);
			System.out.println(aClass.getName());
		 }
		
	}
}



泛型 
好处: 安全,避免了强制转换的麻烦


一个ArrayList<Integer>用反射来添加String元素

package day2;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
//反射 一个ArrayList<Integer>参数化类型 可以添加String实际类型参数
public class ReflectGeneric
{	
	public static void main(String[] args)throws Exception
	{
		List<Integer> list=new ArrayList<Integer>();
		list.add(1);
		System.out.println(list);
		
		//反射 获取add方法 
		Method addMethod=list.getClass().getMethod("add", Object.class);
		
		addMethod.invoke(list, new String("星星点灯"));
		
		System.out.println(list);
	}
}




ArrayList<E> 代表泛型类型 
ArrayList<E> E代表类型变量,类型参数
ArrayList<Integer> 称为参数化类型
ArrayList<Integer> Integer称为类型参数,或类型参数实例
ArrayList<Integer> 念ArrayList typeof Integer
ArrayList 代表原始类型


参数化类型可以引用一个原始类型
Collection col=new ArrayList<Integer>();
原始类型可以引用一个参数化类型
Collection<Integer> col=new ArrayList();


参数化类型不存在继承关系
<String>  <object>   //不行
<Object>   <String>  //不行


在创建数组实例时,数组元素不能使用参数化类型
Vector<Integer>[] vectors=new Vector<Integer>[10]; //这是不允许的


思考题:
Vector v=new Vector<Integer>();//参数类类型引用给原始类型 允许的
Vector<Object> v1= v;  //原始类型类参数化类型 可以的 


泛型通配符扩展应用


? 代表任意类型,不确定的类型


只能作为传参引用时,调用与添加有关的参数时不行,只能调用与参数类型无关的方法


上限符:
<? extends Number>   只能接收Number或者该子类


下限符:
<? super Integer>   只能接收Integer以及他的父类


限定符总是包括自己


package day2;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

//泛型通配符扩展应用
public class GenericTest
{
	public static void main(String[] args)
	{
	//	print(new int[]{1,2,3}); //编译错误, 基本类型不能当作为实际参数
		print(new String[]{"a","b"}); //可以, 引用类型数组可以
		
		ArrayList<Integer> aList=new ArrayList<Integer>();
		aList.add(10);
		aList.add(1);
		
		//show(aList);
		show1(aList);
		
		//上限符
		ArrayList<? extends Number> al1=new ArrayList<Integer>();
		
		
		//下限符
		ArrayList<? super Integer> al3=new ArrayList<Integer>();
		//String 不是Integer的父类
		//ArrayList<? super Integer> al2=new ArrayList<String>();
		
		
 	}
	public static <T> void print(T [] arr)
	{
		System.out.println(arr.length);
	}
	// ?代表不确定的类型 任意类型
	public static void show(Collection<?> c)
	{
		//当?作为引用是时, 不能调用与添加有关的方法,只能使用与参数类型无关的方法
	
		System.out.println(c.toString());
		//c.add(1);  不能使用
		c.clear();
	}
	//T 代表确定的类型 
	public static <T> void show1(Collection<T> c)
	{
		//当?作为引用是时, 不能调用与添加有关的方法,只能使用与参数类型无关的方法
	
		System.out.println(c.toString());
		//c.add(1);  不能使用
		Iterator<T> it=c.iterator();
		while (it.hasNext())
		{
			T t=it.next();
			System.out.println(t);
			
		}
		
	}
}



泛型的综合案例,  HashMap添加元素


package day1;

import java.util.HashMap;
import java.util.Map;


//泛型实例 Map
public class EnhanceFor
{
	public static void main(String[] args)
	{
		Map<String, String> map = new HashMap<String, String>();
		map.put("key1", "value1");
		map.put("key2", "value2");
		map.put("key3", "value3");
		
		for (Map.Entry<String, String> mEntry : map.entrySet())
		{
			System.out.println(mEntry.getKey()+"---"+mEntry.getValue());
		}
	



自定义泛型方法
// x y 可以传入任意类型, 最大的交集就是Object 
private static <T> T add (T x , T y)
{
//return x+y; 这是不允许的,因为类型的不确定是否能运算
return x;
}


java泛型完全是在编译器中实现的


T不能是基本类型,只能是引用类型,才能作为实际参数


<V extends Serializable&Cloneable> 必须实现这两接口的类型


普通类,构造方法,静态方法,都可以使用泛型


数组实例不能使用参数化类型


泛型参数可以有多个,例如Map<K,V>


泛型的类型推断还有传递性


泛型类
 

 静态不能使用泛型类


package day2;
//泛型类
public class GenericClass<T>
{
	@SuppressWarnings("unused")
	private T t;
	/*
	//静态方法不能使用 类泛型
	public static void show(T t)
	{
		
	}
	*/
	public static <T> void method(T t)
	{
		
	}
	
	public void show(T t)
	{
		System.out.println(t);
	}
	
}




 通过反射获取泛型的实际参数类型
 
 getGenericParamterTypes();
 getParameterTypes();
 ParameterizedType参数化类型类
 
 getRawType();
 getActualTypeArguments();

 

package day2;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;

//反射获取参数泛型类型
public class GenericTest1
{
	public static void main(String[] args)throws Exception
	{
		show(new String("尼玛"));
		show(new Integer(1));
		
		Method method=GenericTest1.class.getMethod("print", Collection.class);
		
		Type[] types = method.getGenericParameterTypes();
		
		ParameterizedType pType=(ParameterizedType)types[0];
		
		System.out.println(pType.getRawType());
	//	System.out.println(pType.getActualTypeArguments()[0]);
		Type[] types2=pType.getActualTypeArguments();
		System.out.println(types2[0]);
		

	}
	//接收任意类型并打印
	public static <T> void show(T t)
	{
		System.out.println(t);
	}
	public static void print(Collection<String> collection)
	{
		
	}
}


 类加载器   加载类的工具


 系统默认的三个主要加载器
 1.BootStrap   查找rt.jar
 2.ExtClassLoader 查找ext/下的jar包
 3.AppClassLoader 查找classpath路径
 
 类加载器也是java类,BootStrap不是,是c写的二进制文件
 
类.getClassLoader();获取当前类的类加载器
getParent();  //获取父类


因为BootStrap不是java类,所以返回null


java中所有的类加载都是采用父子关系的树状结构图进行组织


ClassLoader类

package day3;
//遍历 类加载器
public class ClassLoaderbase
{
	public static void main(String[] args)
	{
		ClassLoader loader=ClassLoaderbase.class.getClassLoader();
		System.out.println(loader);
		while(loader!=null)
		{
			loader=loader.getParent();
			System.out.println(loader);
		}
		
		//最顶级的父类BootStrap因为不是java类 所以返回null
	}
	
}




类加载器的委托机制
首先会找对顶级的父类,如果没有就一级一级的往下查找,如果到了触发者这里还没有就抛ClassNotFoundException


自定义加密Class文件
自定义解密Class文件

package day3;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

import com.sun.org.apache.bcel.internal.util.ByteSequence;

//加解密 自动加载器类
@SuppressWarnings("unused")
public class MyClassLoader  extends ClassLoader
{

	private String classDir;
	public MyClassLoader(String classDir)
	{
		this.classDir=classDir;
	}
	public static void main(String[] args)throws Exception
	{
		String yuan=args[0];
		String filename=yuan.substring(yuan.lastIndexOf(File.separator)+1);
		String mudi=args[1]+File.separator+filename;
		
		FileInputStream fis=new FileInputStream(yuan);
		FileOutputStream fos=new FileOutputStream(mudi);
		EncryptionAndDecryption(fis, fos);
		
		
	}
	public static void EncryptionAndDecryption(InputStream inStream,OutputStream outStream)
	{
		try
		{
			int b=0;
			while((b=inStream.read())!=-1)
			{
				outStream.write(b ^ 0xff);
			}
		} catch (Exception e)
		{
			System.out.println("加解密文件失败");
		}finally
		{
			try
			{
				if(inStream != null)
					inStream.close();
			} catch (Exception e2)
			{
				System.out.println("关流失败");
			}
			try
			{
				if(outStream != null)
					outStream.close();
			} catch (Exception e2)
			{
				System.out.println("关流失败");
			}
		}
	}
	//只需要复写findClass方法 就可以自动以类加载器了
	@SuppressWarnings("deprecation")
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException
	{
		// TODO Auto-generated method stub
		String filePath=classDir+File.separator+name+".class";
		try
		{
			FileInputStream inStream=new FileInputStream(filePath);
			
			ByteArrayOutputStream baos=new ByteArrayOutputStream();
			
			EncryptionAndDecryption(inStream, baos);
			
			inStream.close();
			
			byte[]buf =baos.toByteArray();
			
			return defineClass(buf, 0, buf.length);
			
		} catch (Exception e)
		{
			// TODO: handle exception
		}
		
		return null;
	}
}


package day3;


public class ClassLoaderTest
{
	public static void main(String[] args)throws Exception
	{
		//使用已经加密的class文件new 运行出错
		//System.out.println(new Test());
		new MyClassLoader("E:\\android\\projects\\javaenhance1\\bin\\day3").loadClass("Test").newInstance();
	}
}


loadClass();加载类
  我们只需要复写findClass路径添加为自己的路径即可
  
  defineClass(); 接收字节数组返回class
  
 有包的类不能调用无包的类
 
一个类加载器的高级问题分析web




代理的概念与作用
Proxy代理


AOP (Aspect Oriented Program) 面向方面的编程


安全,事物,日志等功能要贯穿好多个模块中,他们就是交叉业务


AOP中,将交叉业务模块化,可以将切面代码异移动到原始方法的周围


动态代理技术


jvm自动生成类, 动态生成类,即动态代理类


package day3;

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

//动态代理类  演示
public class ProxyTest
{
	public static void main(String[] args)
	{
		Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
		
		Constructor[] constructors=clazz.getConstructors();
		for (Constructor constructor : constructors)
		{
			StringBuilder sbBuilder=new StringBuilder(constructor.getName());
			
			Class[] classes=constructor.getParameterTypes();
			sbBuilder.append('(');
			for (Class class1 : classes)
			{
				sbBuilder.append(class1.getName());
			}
			if(classes!= null && classes.length!=0)
				sbBuilder.deleteCharAt(sbBuilder.length()-1);
			sbBuilder.append(')');
			
			System.out.println(sbBuilder.toString());
		}
		
		Method[] methods=clazz.getMethods();
		for (Method method : methods)
		{
			StringBuilder sbBuilder=new StringBuilder(method.getName());
			Class[]classes=method.getParameterTypes();
			sbBuilder.append('(');
			for (Class classs : classes)
			{
				sbBuilder.append(classs.getCanonicalName());
			}
			sbBuilder.append(')');
			System.out.println(sbBuilder.toString());
		}
	}
}



动态代理生成必须实现一个或多个接口  


CGLIB可以生成没有接口的子类,代理类


Proxy.getProxyClass(); 
Proxy.newProxyInstance();

package day3;

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


//代理类实例化
public class ProxyTest1
{
	public static void main(String[] args)throws Exception
	{
		
		//麻烦的实例化代理对象做法
		
	
		Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
		
		Constructor constructor=clazz.getConstructor(InvocationHandler.class);
		
		Collection collection=(Collection)constructor.newInstance(new InvocationHandler()
		{
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
			{
				// TODO Auto-generated method stub
				return null;
			}
		});
		//返回为空
		System.out.println(collection);
		System.out.println(collection.toString());
		//collection.add("add");//不能添加
		System.out.println(collection.size()); //null  不能调用需要实例化对象的方法
		
		
		//简单的一部到位做法
		
		Collection collection1=(Collection)Proxy.newProxyInstance(
				Collection.class.getClassLoader(), 
				new Class[]{Collection.class},
				new InvocationHandler()
				{
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
					{
						// TODO Auto-generated method stub
						return null;
					}
				});
		//返回为空
				System.out.println(collection1);
				System.out.println(collection1.toString());
				//collection.add("add");//不能添加
				System.out.println(collection1.size()); //null  不能调用需要实例化对象的
	}
}



要有一个目标,一个建议


Client程序用Proxy的方法时,涉及三要素:代理对象 , 代理对象的方法, 方法参数


把目标返回结果返回到代理上


可以将代码封装对象,放在原方法的四个位置:
1.前
2.后
3.中间
4.catch处理代码块中


建议Advice接口  
目标就是要生成代理类的类

package day3;

import java.lang.reflect.Method;

public interface Advice
{
	void beforMethod(Method method);
	void affterMethod(Method method);
}


package day3;

import java.lang.reflect.Method;

public class MyAdvice implements Advice
{
	private long startTime;
	private long endTime;
	@Override
	public void beforMethod(Method method)
	{
		startTime=System.currentTimeMillis();
		System.out.println("事物,安全,日志    代码前 ");

		System.out.println("方法名"+method.getName());
	}

	@Override
	public void affterMethod(Method method)
	{
		
		endTime=System.currentTimeMillis();
		System.out.println("执行所花费时间:"+(endTime-startTime));
		System.out.println("事物,安全,日志    代码后 ");
	}

}



package day3;

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 ProxyTest3
{
	public static void main(String[] args)
	{
		final ArrayList target=new ArrayList();
		final Advice advice=new MyAdvice();
		
		Collection collection=(Collection)getProxy(target, advice);
		collection.add("dd");
	}

	private static Object getProxy(final ArrayList target, final Advice advice)
	{
		Object object = Proxy.newProxyInstance(
				target.getClass().getClassLoader()
				, target.getClass().getInterfaces()
				, new InvocationHandler()
				{
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable
					{
						advice.beforMethod(method);
						Object returnVal=method.invoke(target, args);
						advice.affterMethod(method);
						return returnVal;
					}
				});
		return object;
	}
}



实现类似Spring中的Aop框架
BeanFactory
getBean();
ProxyFactoryBean

getProxy();


package day3;

import java.io.InputStream;

public class AOPTest
{
	public static void main(String[] args)
	{
		InputStream inStream=AOPTest.class.getResourceAsStream("lib/aop.properties");
		Object object = new BeanFactory(inStream).getBean("className");
		System.out.println(object);
	}
}

package day3;

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


public class BeanFactory
{
	private Properties properties=new Properties();
	public BeanFactory(InputStream inStream)
	{
		try
		{
			properties.load(inStream);
		} catch (Exception e)
		{
			// TODO: handle exception
		}
	}
	@SuppressWarnings("rawtypes")
	public Object getBean(String name)
	{
		Object bean=null;
		String className=properties.getProperty(name);
		try
		{
			Class clazz=Class.forName(className);
			bean=clazz.newInstance();
		} catch (Exception e)
		{
			// TODO: handle exception
		}
		if(bean instanceof ProxyFactoryBean)
		{
			Object proxy=null;
			ProxyFactoryBean pBean=(ProxyFactoryBean)bean;
			try
			{
				Advice advice=(Advice)Class.forName(properties.getProperty(name+".advice")).newInstance();
				Object target=Class.forName(properties.getProperty(name+".target")).newInstance();
				pBean.setAdvice(advice);;
				pBean.setTarget(target);
				
				proxy = pBean.getProxy();
				
				return proxy;
			} catch (Exception e)
			{
				System.out.println("获取异常");
			}
		}
		return bean;
	}
}

package day3;

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 this.target;
	}

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

	public Advice getAdvice()
	{
		return this.advice;
	}

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

	public Object getProxy()
	{
		final Object target=getTarget();
		final Advice advice=getAdvice();
		Object object = Proxy.newProxyInstance(
				target.getClass().getClassLoader(),
				target.getClass().getInterfaces(),
				new InvocationHandler()
				{
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
					{
						advice.beforMethod(method);
						Object returnValue=method.invoke(target, args);
						advice.affterMethod(method);
						return returnValue;
					}
				});
		return object;
	}
}


 —————————— ASP.Net+Android+IOS开发.Net培训、期待与您交流!——————————

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值