0
点赞
收藏
分享

微信扫一扫

Spring用手写注解和反射机制模拟Spring全注解开发本质-----Spring框架

package com.powernode.client;
 
import com.powernode.annotation.Component;
 
import java.io.File;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
 
public class ComponentScan
{
    public static void main(String[] args) throws Exception
    {
        //包的名字
        String packageName = "com.powernode.bean";
        //扫描该路径
        String packagePath = packageName.replaceAll("\\.","/");
        //这个.在正则表达式中可以代表任意字符,这里的.必须是一个普通的符号
        //在正则表达式中要用\\.代替一个普通的.符号
        System.out.println(packagePath);
        //com是在类的根路径下的一个路径,所以
        URL url = ClassLoader.getSystemClassLoader().getResource(packagePath);
        //拿到了绝对路径
        String path = url.getPath();
//        System.out.println(path);
        //获取一个绝对路径下的文件
        File file = new File(path);
        File[] files = file.listFiles();
        HashMap<String,Object> map = new HashMap<>();
        Arrays.stream(files).forEach(file1 -> {
            try
            {
                String ClassName = file1.getName().split("\\.")[0];
                System.out.println(ClassName);
                ClassName = packageName + "." + file1.getName().split("\\.")[0];
                System.out.println(ClassName);
                Class<?> clazz = Class.forName(ClassName);
                //判断类上是否有该注解
                if(clazz.isAnnotationPresent(Component.class))
                {
                    Component component = clazz.getAnnotation(Component.class);
                    String id = component.value();
                    Object o = clazz.getDeclaredConstructor().newInstance();
                    map.put(id,o);
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        });
        Iterator iterator = map.entrySet().iterator();
        while (iterator.hasNext())
        {
            Map.Entry entry = (Map.Entry) iterator.next();
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }
    }
}

package com.powernode.client;
 
import com.powernode.annotation.Component;
import com.powernode.annotation.MyAnnotation;
 
public class ReflectAnnotation
{
    public static void main(String[] args) throws Exception
    {
        //通过反射机制怎么读取注解
        Class<?> clazz = Class.forName("com.powernode.bean.User");
        if(clazz.isAnnotationPresent(Component.class))
        {
            //判断这个类上有没有该注解,如果有,我们再获取注解
            Component annotation = clazz.getAnnotation(Component.class);
            System.out.println(annotation.value());
        }
        if(clazz.isAnnotationPresent(MyAnnotation.class))
        {
            MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
            System.out.println(annotation.type());
        }
    }
}

package com.powernode.annotation;
 
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
//自定义注解
@Target({ElementType.TYPE})//标注注解的注解,叫做元注解,Target用来修饰Component可以出现的位置,内部可以填入一个ElementType的数组
//该注解表示Component可以出现在类上和属性上
//当某个注解内只有一个元素,可以不要大括号,直接填入
@Retention(RetentionPolicy.RUNTIME)
//标注Component注解最终保留在Class文件中,可以被反射机制读取(如果要被反射机制读取就得加)
//Class文件和编译出的文件都有,RUNTIME全程运行都有,Source仅源文件有
public @interface Component
{
    //定义注解的属性
    //String是属性类型
    //value是属性名
    String value();
    //其他的属性
    //属性类型是String
    //属性名是name
//    String name();
    //数组类型
    //属性名是names
//    String[] names();
//    int age();
//    int[] ages();
}

package com.powernode.annotation;
 
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 MyAnnotation
{
    String type();
}

package com.powernode.bean;
 
import com.powernode.annotation.Component;
 
@Component("userBean")
//如果属性名是Value,value可以省略
//用法是属性名 = 属性值,属性名 = 属性值,属性名 = 属性值
public class User
{
//    不能在这里出现,因为注解标注没有在此处的
//    @Component(value = "test")
    private String name;
 
}

package com.powernode.bean;
 
import com.powernode.annotation.Component;
 
public class Order
{
}

package com.powernode.bean;
 
import com.powernode.annotation.Component;
 
@Component("vipBean")
public class Vip {
}

举报

相关推荐

0 条评论