浅析注解/反射,反射的最佳实践(模拟一个简单框架)

参考的视频

# Java中的反射 Reflection in Java

本文说明

本文只是提供参考视频中讲解人讲解模拟框架的代码,不包含框架基本信息的讲解。如果想要了解反射的基本信息,极力推荐观看参考视频。

那是一个非常精彩的视频,如果你和我一样是新手小白,观看完视频后,会让你对反射和注解有个新的认知。

代码仓库

#反射的最佳实践-code

项目结构

在这里插入图片描述

package1

autowired
package com.example.package1;  
  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})  
@Retention(RetentionPolicy.RUNTIME)  
public @interface Autowired {  
}
Bean
package com.example.package1;  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface Bean {  
}
Printable
package com.example.package1;  
import java.lang.annotation.ElementType;  
import java.lang.annotation.Retention;  
import java.lang.annotation.RetentionPolicy;  
import java.lang.annotation.Target;  
  
@Target(ElementType.METHOD)  
@Retention(RetentionPolicy.RUNTIME)  
public @interface Printable {  
}

package2

Config
package com.example.package2;  
  
import com.example.package1.Bean;  
import com.example.package3.Address;  
import com.example.package3.Customer;  
  
public class Config {  
    @Bean  
    public Customer customer() {  
        return new Customer("pony", "pony@qq.com");  
    }  
  
    @Bean  
    public Address address() {  
        return new Address("center street", "114514");  
    }  
  
}
Container
package com.example.package2;  
  
import com.example.package1.Autowired;  
import com.example.package1.Bean;  
  
import java.lang.reflect.Constructor;  
import java.lang.reflect.InvocationTargetException;  
import java.lang.reflect.Method;  
import java.util.HashMap;  
import java.util.Map;  
  
public class Container {  
    private Map<Class<?>, Method> map;   // 储存的是 加@Bean注解的方法  
  
    private Map<Class<?>, Object> instanceMap;  // 实现单例  
    private Object config;  
  
    public void init() throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException {  
        map = new HashMap<>();  
        instanceMap = new HashMap<>();  
        Class<?> aClass = Class.forName("com.example.package2.Config");  
        Method[] methods = aClass.getDeclaredMethods();  
        for (Method method : methods) {  
            if (method.getAnnotation(Bean.class) != null)  
                this.map.put(method.getReturnType(), method);  // 拿到所有生成对象的方法  
        }  
        this.config = aClass.getConstructor().newInstance(); // 获得可以调用 map 集合方法生成实例的对象  
  
    }  
  
    public Object getServiceInstanceByClass(Class<?> clazz) throws InvocationTargetException, IllegalAccessException {  
        if (this.map.containsKey(clazz)) {  
            if (!this.instanceMap.containsKey(clazz)) {  
                Method method = map.get(clazz);  
                Object instance = method.invoke(config);  
                this.instanceMap.put(clazz, instance);  
            }  
            return this.instanceMap.get(clazz);  
        }  
        return null;  
    }  
  
    public Object createInstance(Class<?> clazz) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException {  
        Constructor<?>[] constructors = clazz.getConstructors();  
        for (Constructor<?> constructor : constructors) {  
            if (constructor.getAnnotation(Autowired.class) != null) {  
                Class<?>[] parameterTypes = constructor.getParameterTypes();  
                Object[] argument = new Object[parameterTypes.length];  
                for (int i = 0; i < argument.length; i++) {  
                    argument[i] = getServiceInstanceByClass(parameterTypes[i]);  
                }  
                return constructor.newInstance(argument);  
            }  
        }  
        return clazz.getConstructor().newInstance();  
    }  
  
  
}

package3

Address
package com.example.package3;  
  
  
public class Address {  
    public String street;  
  
    public String postCode;  
  
    public Address() {  
  
    }  
  
    public Address(String street, String postCode) {  
        this.street = street;  
        this.postCode = postCode;  
    }  
  
    public void printStreet() {  
        System.out.println(this.street);  
    }  
  
    public void printPostCode() {  
        System.out.println(this.postCode);  
    }  
  
}
Customer
package com.example.package3;  
  
import com.example.package1.Printable;  
  
public class Customer {  
    private String name;  
    private String email;  
  
  
    public Customer(String name, String email) {  
        this.name = name;  
        this.email = email;  
    }  
  
    public Customer() {  
    }  
  
    @Printable  
    public void printEmail() {  
        System.out.println(email);  
    }  
  
    public void printName() {  
        System.out.println(name);  
    }  
  
}
Order
package com.example.package3;  
  
import com.example.package1.Autowired;  
import com.example.package3.Address;  
import com.example.package3.Customer;  
  
public class Order {  
    private Customer customer;  
    private Address address;  
  
    public Order() {  
  
    }  
    @Autowired  
    public Order(Customer customer, Address address) {  
        this.customer = customer;  
        this.address = address;  
    }  
      
}

Main

package com.example;  
  
  
import com.example.package1.Printable;  
import com.example.package2.Container;  
import com.example.package3.Customer;  
import java.lang.reflect.Field;  
import java.lang.reflect.InvocationTargetException;  
import java.lang.reflect.Method;  
  
public class Main {  
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, NoSuchMethodException, InstantiationException, NoSuchFieldException {  
        Container container = new Container();  
        container.init();  
          
        String className = "com.example.package3.Order";  
        String fieldName = "customer";  
          
        Class<?> clazz = Class.forName(className);  
        Object instance = container.createInstance(clazz);  
        Field filed = clazz.getDeclaredField(fieldName);  
        filed.setAccessible(true);  
        Object fieldValue = filed.get(instance);  
          
        System.out.println(fieldValue);  
  
        Method[] methods = fieldValue.getClass().getDeclaredMethods();  
        for (Method method : methods) {  
            if (method.getAnnotation(Printable.class) != null) {  
                System.out.println(method.getName());  
                method.invoke(fieldValue);  
            }  
        }  
  
        System.out.println(fieldValue == container.getServiceInstanceByClass(Customer.class)); // true  
        }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值