2021-09-16

ioc

创建注解

@ComponentScan

package org.example.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 ComponentScan {
    String value();
}

@Component

package org.example.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 Component {
    String value() ;
}

@Scope

package org.example.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 Scope {
    String value() default "";
}

扫包类

package org.example;

import org.example.annotation.ComponentScan;

@ComponentScan("org.example")
public class MyApplication {
}

需要交给spring容器管理类

package org.example.service;

import org.example.annotation.Component;
import org.example.annotation.Scope;

@Component("userService")
@Scope("prototype")
public class UserService {
    public void test(){
        System.out.println("true = " );
    }
}

ApplicationContext

package org.example;

import org.example.annotation.Component;
import org.example.annotation.ComponentScan;
import org.example.annotation.Scope;
import org.example.common.BeanDefinition;

import java.io.File;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.IntFunction;


public class ApplicationContext {
    private ConcurrentHashMap<String,Object> singleMaps=new ConcurrentHashMap<String,Object>();
    private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap=new ConcurrentHashMap<String, BeanDefinition>();
    private Class<?> clazz;

    public ApplicationContext(Class<?> clazz) {
        this.clazz = clazz;
    }

    public void scan(){

        //判断类上是否有ComponentScan
        if (clazz.isAnnotationPresent(ComponentScan.class)){
            ComponentScan annotation = (ComponentScan) clazz.getDeclaredAnnotation(ComponentScan.class);
            String value = annotation.value();
            //利用类加载器加载配置目录获取所有子文件
            ClassLoader classLoader = clazz.getClassLoader();
            String s = value.replaceAll("\\.", "/");
            URL url = classLoader.getResource(s);
            File file = new File(url.getFile());
            if (file.isDirectory()){
                ArrayList<File> list = new ArrayList<>();
                getAllFile(file,list);
                File[] files = list.stream().toArray(new IntFunction<File[]>() {
                    @Override
                    public File[] apply(int value) {
                        return new File[value];
                    }
                });
                //遍历判断是否包含Component注解 有则创建实例
                assert files != null;
                for (File file1 : files) {
                    if (file1.isFile()){
                        String path = file1.getPath();
                        try {
                            Class<?> aClass = classLoader.loadClass(path.substring(path.indexOf("org"), path.indexOf(".")).replace("\\","."));
                            if (aClass.isAnnotationPresent(Component.class)){
                                Component component = aClass.getAnnotation(Component.class);
                                String beanName = component.value();
                                BeanDefinition beanDefinition = new BeanDefinition();
                                if (aClass.isAnnotationPresent(Scope.class)){
                                    Scope scope = aClass.getAnnotation(Scope.class);
                                    //原型
                                         beanDefinition.setScope(scope.value());
                                }else{
                                    //单例
                                    beanDefinition.setScope("singleton");
                                    singleMaps.put(beanName,aClass.getDeclaredConstructor().newInstance());
                                }
                                beanDefinition.setClazz(aClass);
                                beanDefinitionMap.put(beanName,beanDefinition);
                            }
                        } catch (ClassNotFoundException | NoSuchMethodException e) {
                            e.printStackTrace();
                            throw new RuntimeException(path+"类加载失败");
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        } catch (InstantiationException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }

                }
            }else{
                throw new RuntimeException("配置项非文件");
            }

        }
    }

    //递归 循环遍历取出一个目录下所有文件(去除目录)
    private void getAllFile(File file, List<File> files){
        if (file.isDirectory()){
            File[] files1 = file.listFiles();
            for (File file1 : files1) {
               getAllFile(file1,files);
            }

        }else if (file.isFile()){
            files.add(file);
        }
    }

    private Object createBean(Class<?> clazz){
        try {
            return clazz.getDeclaredConstructor().newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }
    public Object getBean(String beanName){
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition!=null){
            if ("singleton".equals(beanDefinition.getScope())){
                    return singleMaps.get(beanName);
            }else if ("prototype".equals(beanDefinition.getScope())){
                    return createBean(beanDefinition.getClazz());
            }
        }
        return null;
    }


}

测试

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ApplicationContext(MyApplication.class);
        applicationContext.scan();
        System.out.println("applicationContext.getBean(\"userService\") = " + applicationContext.getBean("userService"));
        System.out.println("applicationContext.getBean(\"userService\") = " + applicationContext.getBean("userService"));
        System.out.println("applicationContext.getBean(\"userService\") = " + applicationContext.getBean("userService"));
        System.out.println("applicationContext.getBean(\"userService\") = " + applicationContext.getBean("userService"));
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值