• Java-day17(反射)


    Reflection(反射)

    动态语言的关键

    • 允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法
    • 提供的功能:
      在运行时判断任意一个对象所属类
      在运行时构造任意一个类的对象
      在运行时判断任意一个类所具有的成员变量和方法
      在运行时调用任意一个对象的成员变量和方法
      生成动态代理
      在这里插入图片描述


    Person类

    @MyAnnotation(value = "atguigu")
    public class Person extends Creature<String> implements Comparable,MyInsterface{   
    	public String name;
    	private int age;
    	//创建类时,尽量保留一个空参的构造器
    	public Person() {
    		super();
    		System.out.print("空参");
    	}
    	public Person(String name) {
    		super();
    		this.name = name;
    	}
    	public Person(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    	
    	
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	@MyAnnotation(value = "boos")
    	public void show() {
    		System.out.println("I am Person");
    	}
    	public void display(String nation)throws Exception {
    		System.out.println("我的国籍是= " + nation);
    	}
    	private Integer displays(String nation,Integer i)throws Exception {
    		System.out.println("我的国籍是= " + nation);
    		return i;
    	}
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + "]";
    	}
    	@Override
    	public int compareTo(Object arg0) {
    		// TODO Auto-generated method stub
    		return 0;
    	}
    	public static void info() {
    		System.out.println("Chianese");
    	}
    	class A {
    		
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    在这里插入图片描述

    • 没有反射之前,创建对象,调用方法,属性
    @Test
    public void test1() throws Exception {
    	Person p = new Person();
    	p.setName("HaoJie");
    	p.setAge(22);
    	System.out.println(p);                             
    	p.show();
    	p.display("中国");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 有反射之后,创建对象,调用方法,属性
    @Test
    public void test2() throws Exception{
    	Class c = Person.class;//c直接指向Person实体(反射的源头java.lang.Class类)
    	//1.创建c对应的运行时类Person类的对象
    	Person p = (Person)c.newInstance();
    	//2-1.通过反射获取实体的公有属性
    	Field f1 = c.getField("name");
    	f1.set(p,"LiYunHai");
    	System.out.println(p);       
    	//2-2.通过反射获取实体的私有属性
    	Field f2 = c.getDeclaredField("age");
    	f2.setAccessible(true);
    	f2.set(p,26);
    	System.out.println(p);  
    	
    	//通过反射调用运行时实体(类)的指定的方法
    	Method m1 = c.getMethod("show");
    	m1.invoke(p);
    	
    	Method m2 = c.getMethod("display",String.class);
    	m2.invoke(p,"China");		
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    1.理解Class类并实例化Class类对象

    在这里插入图片描述

    • 类的具体实现:
      在这里插入图片描述

      创建类,通过编译(javac.exe),生产字节码文件,之后通过java.exe加载(JVM的类加载器完成的)字节码文件,字节码文件加载到内存中,就是一个运行时类,存在缓冲区中。这个运行时类本身就是一个Class的实例
      在这里插入图片描述

    • 每一个运行时类只加载一次

    • 有Class的实例,就可以进行如下操作:

       //*创建对应的运行时类的对象
       //获取对应的运行时类的完整结构(属性,方法,构造器,内部类。。。)
       //*调用对应运行时类的指定的结构(属性,方法,构造器)
       //反射的应用:动态代理
      
      • 1
      • 2
      • 3
      • 4

    获取Class的实例(掌握3种)

    @Test
    public void test4() throws ClassNotFoundException {
    	//1.调用运行时类本身的.class属性
    	Class clazz = Person.class;
    	System.out.println(clazz.getName());                
    	
    	Class clazz1 = String.class;
    	System.out.println(clazz1.getName());
    	System.out.println();
    	
    	//2.通过运行时类的对象获取
    	Person p = new Person();
    	Class clazz2  = p.getClass();
    	System.out.println(clazz2.getName());
    	
    	//3.通过Class的静态方法获取
    	String classname = "java.lang.String";
    	Class clazz3 = Class.forName(classname);
    	System.out.println(clazz3.getName());
    	
    	//4.(了解)通过类的加载器
    	ClassLoader classLoader = this.getClass().getClassLoader();
    	Class clazz4 = classLoader.loadClass(classname);
    	System.out.println(clazz4.getName());
    	
    	System.out.println(clazz1 == clazz3);//true
    	System.out.println(clazz1 == clazz2);//false
    	System.out.println(clazz1 == clazz4);//true
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在这里插入图片描述
    例:

    @Test	
    	public void test5() throws IOException {
    		ClassLoader loader1 = ClassLoader.getSystemClassLoader();          
    		System.out.println(loader1);//获取ClassLoader类的加载类AppClassLoader
    		
    		ClassLoader loader2 = loader1.getParent();
    		System.out.println(loader2);//ExtClassLoader
    		
    		ClassLoader loader3 = loader2.getParent();
    		System.out.println(loader3);//null(核心类库及引导类无法获取)
    		
    		
    		Class clazz1 = Person.class;
    		ClassLoader loader4 = clazz1.getClassLoader();
    		System.out.println(loader4);//AppClassLoader
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    	//掌握如下:查找包下的文件中的部分内容
    		ClassLoader loader5 = this.getClass().getClassLoader();                  
    		InputStream is = loader5.getResourceAsStream("hello.txt");
    		//查找工程下的文件中的部分内容
    	//FileInputStream is = new FileInputStream(new File("hello.txt"));
    		Properties txt = new Properties();
    		txt.load(is);
    		String name = txt.getProperty("user");
    		System.out.println(name);
    		String password = txt.getProperty("password");
    		System.out.println(password);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.在运行时创建类对象并获取类的完整结构

    在这里插入图片描述
    例:

    @Test
    	public void test1() throws Exception {
    		String className = "Person";                       
    		Class clazz = Class.forName(className);  
    		//创建对应的运行类的对象
    		//要求:1.对应的运行时类要有空参的构造器;2.构造器的权限应在缺省(及以上)
    		Object obj = clazz.newInstance();
    		Person p = (Person)obj;
    		System.out.print(p);  
    	}
    	
    	@Test
    	//构造器
    	public void test2() throws ClassNotFoundException {
    		String className = "Person";  
    		Class clazz = Class.forName(className);  
    		//getDeclaredConstructors():获取本身类所有的构造器
    		Constructor[] cons = clazz.getDeclaredConstructors();
    		for(Constructor c : cons) {  
    			System.out.println(c);  
    	}
    		}
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    获取运行时类的方法
    @Test
    	public void test1() {
    		Class clazz = Person.class;
    		//1.getMethods():获取运行时类及其父类中所有声明为public的方法
    		Method[] m1 = clazz.getMethods();
    		for(Method m : m1) {       
    			System.out.println(m);
    		}
    		System.out.println();
    		
    		//2.获取运行时类本身声明的所有方法
    		Method[] m2 = clazz.getDeclaredMethods();
    		for(Method m : m2) {
    			System.out.println(m);
    		}
    		System.out.println();
    		System.out.println();
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    获取对应的运行时类的属性
    @Test
    	public void test1() {
    		Class clazz = Person.class;
    		//getFields():只能获取运行时类及其父类中声明为public的属性
    		Field[] fields = clazz.getFields();
    		for(int i = 0;i < fields.length;i++) {
    			System.out.println(fields[i]);        
    		}
    		System.out.println();
    		
    		//2.getDeclaredFields():获取运行时类本身声明的所有属性
    		Field[] fields1 = clazz.getDeclaredFields();
    		for(Field f : fields1) {
    			System.out.println(f.getName());
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    获取属性各个部分的内容(权限修饰符 变量类型 变量名)
    @Test
        public void test2() {
    		Class clazz = Person.class;
    		Field[] fields = clazz.getDeclaredFields();
    		for(Field f : fields) {
    			//1.获取属性的权限修饰符
    			int i = f.getModifiers();
    			String str = Modifier.toString(i);
    			System.out.print(str + " ");      
    			//2.获取属性的类型
    			Class type = f.getType();
    			System.out.print(type.getName() + " ");
    			//3.获取属性名
    			System.out.print(f.getName());
    			System.out.println();
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    注解 权限修饰符 返回值类型 方法名 形参列表 异常
    @Test
    	public void test2() {
    		Class clazz = Person.class;
    		
    		Method[] m1 = clazz.getDeclaredMethods();
    		for(Method m : m1) {   
    			//1.注解
    			Annotation[] ann = m.getAnnotations();
    			for(Annotation an : ann) {
    				System.out.println(an);
    			}
    			//2.权限修饰符
    			String str = Modifier.toString(m.getModifiers());
    			System.out.print(str + " ");
    			
    			//3.返回值类型
    			Class returnType = m.getReturnType();
    			System.out.print(returnType.getName() + " ");
    			
    			//4.方法名
    			System.out.print(m.getName());
    			
    			//5.形参列表
    			System.out.print("(");
    			Class[] params = m.getParameterTypes();
    			for(int i = 0;i < params.length;i++) {
    				System.out.print(params[i].getName() + " args-" + i + " ");
    			}
    			System.out.print(")");
    			
    			//6.异常类型
    			Class[] exps = m.getExceptionTypes();
    			
    			if(exps.length != 0) {
    				System.out.print("throws ");
    			}
    			for(int i = 0;i < exps.length;i++) {
    				System.out.print(exps[i].getName());
    			}			
    			System.out.println();
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    在这里插入图片描述

    import java.lang.annotation.Retention;         
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    import static java.lang.annotation.ElementType.*;
    @Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR, LOCAL_VARIABLE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
    	String value();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    带泛型的类

    public class Creature<T> {
    	public double weight; 
    	public void breath() {
    		System.out.println("呼吸");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    接口

    import java.io.Serializable;
    
    public interface MyInsterface extends Serializable{
    	
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    继承,实现接口等

    @MyAnnotation(value = "atguigu")
    public class Person extends Creature<String> implements Comparable,MyInsterface{  
    	public String name;
    	private int age;
    	//创建类时,尽量保留一个空参的构造器
    	public Person() {
    		super();
    		System.out.print("空参");
    	}
    	public Person(String name) {
    		super();
    		this.name = name;
    	}
    	public Person(String name, int age) {
    		super();
    		this.name = name;
    		this.age = age;
    	}
    	
    	
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getAge() {
    		return age;
    	}
    	public void setAge(int age) {
    		this.age = age;
    	}
    	@MyAnnotation(value = "boos")
    	public void show() {
    		System.out.println("I am Person");
    	}
    	public void display(String nation)throws Exception {
    		System.out.println("我的国籍是= " + nation);
    	}
    	private Integer displays(String nation,Integer i)throws Exception {
    		System.out.println("我的国籍是= " + nation);
    		return i;
    	}
    	@Override
    	public String toString() {
    		return "Person [name=" + name + ", age=" + age + "]";
    	}
    	@Override
    	public int compareTo(Object arg0) {
    		// TODO Auto-generated method stub
    		return 0;
    	}
    	public static void info() {
    		System.out.println("Chianese");
    	}
    	class A {
    		
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    测试

    import java.lang.annotation.Annotation;             
    import java.lang.reflect.ParameterizedType; 
    import java.lang.reflect.Type; 
    
    import org.junit.Test;
    
    public class TestOther {
    	
    	@Test
    	//1.获取运行时类的父类
    	public void test1() {
    		Class clazz = Person.class;
    		Class superClass = clazz.getSuperclass();
    		System.out.println(superClass);//class Creature 
    	}
    	
    	@Test
    	//2.获取带泛型的父类
    	public void test2() {
    		Class clazz = Person.class;
    		Type type = clazz.getGenericSuperclass();
    		System.out.println(type);//Creature 
    	}
    	
    	@Test
    	//3.获取父类的泛型
    	public void test3() {
    	Class clazz = Person.class;
    	Type type = clazz.getGenericSuperclass();
    	
    	ParameterizedType param = (ParameterizedType)type; 
    	Type[] ars = param.getActualTypeArguments(); 
    	
    	System.out.println(((Class)ars[0]).getName()); 
    	
    	}
    	
    	@Test
    	//获取实现的接口
    	public void test4() {
    		Class clazz = Person.class;
    		Class[] interfaces = clazz.getInterfaces(); 
    		for(Class i : interfaces) { 
    			System.out.println(i); 
    		}
    		
    	}
    	@Test
    	//获取所在的包
    	public void test5() {
    		Class clazz = Person.class;
    		Package pack = clazz.getPackage();
    		System.out.println(pack); 
    	}
    	
    	@Test
    	//获取注解
    	public void test6() {
    		Class clazz = Person.class;
    		Annotation[] anns = clazz.getAnnotations();
    		for(Annotation a : anns) {
    			System.out.println(a); 
    		}
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    3.通过反射调用类的指定方法,指定属性

    调用指定构造器,创建对象
    @Test
    	//
    	public void test3() throws Exception {
    		String className = "Person";    
    		Class clazz = Class.forName(className);
    		
    		Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
    		cons.setAccessible(true);
    		Person p = (Person)cons.newInstance("李福根",56);
    		System.out.println(p);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    调用运行时类中指定的属性
    @Test
    	public void test3() throws Exception {
    		Class clazz = Person.class;
    		//1.获取指定的属性
    		//getField(String fielName):获取运行时类中声明为public类型的指定属性名为fielName的属性
    		Field name = clazz.getField("name");
    		//2.创建运行时类的对象
    		Person p = (Person)clazz.newInstance();
    		System.out.println(p);        
    		//3.将运行时指定的属性赋值
    		name.set(p, "Jame");
    		System.out.println(p);
    		
    		System.out.println();
    		//getDeclaredField(String fielName):获取运行时类中指定属性名为fielName的属性
    		Field age = clazz.getDeclaredField("age");//私有属性不能直接用getField来调
    		//由于权限修饰符的限制,为保证可以给属性赋值,需要在操作前使此属性可被操作(缺省状态下,可不用)
    		age.setAccessible(true);
    		age.set(p, 25);
    		System.out.println(p);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    调用运行时类的指定方法
    @Test
    	public void test3() throws Exception {
    		Class clazz = Person.class;
    		//getMethod(String methodName,Class .. params):获取运行时类中声明为public的指定方法
    		Method m1 = clazz.getMethod("show");
    		Person p = (Person)clazz.newInstance();
    		//调用指定的方法:Object invoke(Object obj,Object ... obj)            
    		Object returnVal = m1.invoke(p);//方法本身无返回值,就显示为null
    		System.out.println(returnVal);
    		
    		Method m2 = clazz.getMethod("toString");
    		Object returnVal1 = m2.invoke(p);
    		System.out.println(returnVal1);//方法本身有返回值,就显示为方法的返回值
    		
    		//调用静态的方法
    		Method m3 = clazz.getMethod("info");
    		m3.invoke(Person.class);//不需要对象
    		
    		
    		//getDeclaredMethod(String methodName,Class .. params):获取运行时类中声明的指定方法
    		Method m4 = clazz.getDeclaredMethod("displays",String.class,Integer.class);
    		m4.setAccessible(true);
    		Object returnVal2 = m4.invoke(p,"CNN",10);//调用方法
    		System.out.println(returnVal2);//返回值
    		
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    4.动态代理与AOP

    静态代理

    package Proxy;     
    //接口
    interface ClothFactory{
    	void productCloth();
    }
    //被代理类
    class NikeClothFactory implements ClothFactory{
    
    	@Override
    	public void productCloth() {
    		System.out.println("Nike工厂开工了!");	
    	}
    }
    
    //代理类
    class ProxyFactory implements ClothFactory{
    	ClothFactory cf;
    	//创建代理类的对象时,实际传入一个被代理类的对象
    	public ProxyFactory(ClothFactory cf) {
    		this.cf = cf;
    	}
    
    	@Override
    	public void productCloth() {
    		System.out.println("代理开始,收专利费了!");
    		cf.productCloth();
    	}
    	
    }
    public class TestCiothProduct {
    	public static void main(String[] args) {	
    	NikeClothFactory nike = new NikeClothFactory();//被代理类
    	ProxyFactory proxy = new ProxyFactory(nike);//代理类
    	proxy.productCloth();
    }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    动态代理

    在这里插入图片描述
    在这里插入图片描述

    package Proxy;  
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    //动态代理
    interface Subject{
    	void action();
    }
    //被代理类
    class ReaSubject implements Subject{
    	public void action() {
    		System.out.println("我是被代理类,好囧ing");
    	}
    }
    
    class MyInvocationHandler implements InvocationHandler{
    	Object obj;//实现接口的被代理类对象的声明
    	
    	//给被代理的对象实例化;返回一个代理类的对象声明
    	public Object blind(Object obj) {
    		this.obj = obj;
    		return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
    	}
    	@Override
    	//当通过代理类的对象发起被重写的方法的调用时,都会转换为对如下invoke方法的调用
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		//method方法的返回值是returnVal
    		System.out.println("代理------");
    		Object returnVal = method.invoke(obj, args);
    		return returnVal;
    	}
    }
    public class dongProxy {
    	public static void main(String[] args) {
    		//1.被代理类的对象
    		ReaSubject real = new ReaSubject();
    		//2.创建实现InvocationHandler接口的类对象
    		MyInvocationHandler handler = new MyInvocationHandler();
    		//3.调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象
    		Object obj = handler.blind(real);
    		Subject sub = (Subject)obj;//此时的sub就是代理类的对象
    		
    		sub.action();//跳转到InvocationHandler接口的实现类的invoke()方法的调用
    		
    		//例
    		NikeClothFactory nike = new NikeClothFactory();//被代理类
    		ClothFactory proxyCloth = (ClothFactory)handler.blind(nike);//proxyCloth即为代理类的对象
    		proxyCloth.productCloth();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    动态代理与AOP

    在这里插入图片描述
    在这里插入图片描述
    例:

    package com.al.java;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    interface Human{
    	void info();
    	void fly();   
    }
    //被代理类
    class SuperMan implements Human{
    	public void info() {
    		System.out.println("我是超人");
    	}
    	public void fly() {
    		System.out.println("I believe I can fly!");
    	}
    }
    class HumanUtil{
    	public void method1() {
    		System.out.println("========方法一======");
    	}
    	public void method2() {
    		System.out.println("========方法二======");
    	}
    }
    
    class MyInvocationHandler implements InvocationHandler{
    	Object obj;
    	public void setObject(Object obj) {
    		this.obj = obj;
    	}
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		HumanUtil h = new HumanUtil();
    		h.method1();
    		Object returnval = method.invoke(obj, args);
    		h.method2();
    		return returnval;
    	}
    	
    	
    }
    
    class MyProxy{
    	//动态的创建一个代理类对象
    	public static Object getProxyInstance(Object obj) {
    		MyInvocationHandler handler = new MyInvocationHandler();
    		handler.setObject(obj);
    		
    		return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),handler);
    	}
    }
    
    public class TestAOP {
    	public static void main(String[] args) {	
    	SuperMan man = new SuperMan();//创建被代理类对象
    	Object obj = MyProxy.getProxyInstance(man);//返回代理类对象
    	Human hu = (Human)obj;
    	hu.info();//通过代理类的对象调用重写的抽象方法
    	System.out.println();
    	hu.fly();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    运行示例
    请添加图片描述
    感谢大家的支持,关注,评论,点赞!
    参考资料:
    尚硅谷宋红康20天搞定Java基础下部

  • 相关阅读:
    实现网站都变成灰色-filter
    GUI编程--PyQt5--布局管理
    WEB自动化_告警框处理(对话框、确认框、提示框、输入/编辑框、勾选框、单选框、复选框、下拉框)
    论文精度 —— 2017 ACM《Globally and Locally Consistent Image Completion》
    P3396 题解
    elasticsearch 搜索引擎+elasticsearch-head+kibana windos环境安装使用手册
    kafka命令之消费者组
    研究研究 ES_OEMCONVERT 标志
    高防服务器和普通服务器之间的区别有哪些
    【VMware vSAN】使用命令行从vSAN集群中移除ESXi主机并加入到新的vSAN集群。
  • 原文地址:https://blog.csdn.net/weixin_51202460/article/details/133280588