Spring - 手写模拟Spring底层原理

手写Spring

定义配置类AppConfig

java 复制代码
@ComponentScan("com.spring.zsj")
public class AppConfig {

    @Bean
    public ApplicationListener applicationListener() {
        return new ApplicationListener() {
            @Override
            public void onApplicationEvent(ApplicationEvent event) {
                System.out.println("接收到了一个事件"+event );
            }
        };
    }

}

定义容器ZSJApplicationContext

java 复制代码
public class ZSJApplicationContext {

    private Class configClass;

    private Map<String,BeanDefinition> beanDefinitionMap =new HashMap<>();//bean定义

    private Map<String,Object> singleObjects = new HashMap<>(); //单例池

    private List<BeanPostProcessor> beanPostProcessorList =new ArrayList<>(); //后置处理

    public ZSJApplicationContext(Class configClass)  {
        this.configClass = configClass;
        scanComponent(configClass);

        //找出单例bean
        for (Map.Entry<String,BeanDefinition> entry: beanDefinitionMap.entrySet()
             ) {
            String beanName = entry.getKey();
            BeanDefinition beanDefinition = entry.getValue();
            if(beanDefinition.equals("singleton")){
                Object bean = createBean(beanName, beanDefinition);
                singleObjects.put(beanName,bean);
            }
        }
    }


    private Object createBean(String beanName,BeanDefinition beanDefinition){
        Class clazz = beanDefinition.getType();
        Object newInstance = null;
        try {
            newInstance =  clazz.getConstructor().newInstance();

            //依赖注入
            for (Field field : clazz.getDeclaredFields()) {
                if (clazz.isAnnotationPresent(Autowired.class)) {
                    field.setAccessible(true);
                    field.set(newInstance, getBean(field.getName()));
                }
            }

            //执行回调方法
            if (newInstance instanceof  BeanNameAware){
                ((BeanNameAware) newInstance).setBeanName(beanName);
            }


            //执行初始化前的方法
            for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) {
                newInstance = beanPostProcessor.postProcessBeforeInitialization(newInstance, beanName);
            }

            //当前对象是否实例化了
            if(newInstance instanceof  InitializingBean){
                ((InitializingBean) newInstance).afterPropertiesSet();
            }

            //执行初始化后的方法(例如Aop)
            for (BeanPostProcessor beanPostProcessor: beanPostProcessorList) {
                newInstance = beanPostProcessor.postProcessAfterInitialization(newInstance, beanName);
            }


        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return newInstance;
    }

    private void scanComponent(Class configClass) {
        if(configClass.isAnnotationPresent(ComponentScan.class)){
            ComponentScan annotation =(ComponentScan) configClass.getAnnotation(ComponentScan.class);
            String path = annotation.value();

             path = path.replace(".", "/");

            ClassLoader classLoader = ZSJApplicationContext.class.getClassLoader();
            URL resource = classLoader.getResource(path);

            File file = new File(resource.getFile());
            if(file.isDirectory()){//若是文件夹,则取出对应的文件
                for (File f: file.listFiles()) {
                    String absolutePath = f.getAbsolutePath();
                    //System.out.println(absolutePath);

                    String com = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
                    String replace = com.replace("\\", ".");
                   // System.out.println(replace);

                    try {
                        Class<?> clazz = classLoader.loadClass(replace);
                        if(clazz.isAnnotationPresent(Component.class)){

                            //clazz 是否实现了BeanPostProcessor接口
                            if(BeanPostProcessor.class.isAssignableFrom(clazz)){
                                BeanPostProcessor instance = (BeanPostProcessor)clazz.getConstructor().newInstance();
                                beanPostProcessorList.add(instance);
                            }

                            //获取bean 的名字
                            Component annotation1 = clazz.getAnnotation(Component.class);
                            String beanName = annotation1.value();
                            if("".equals(beanName)){
                                String name = Introspector.decapitalize(clazz.getSimpleName());
                            }


                            BeanDefinition beanDefinition = new BeanDefinition();
                            beanDefinition.setType(clazz);

                            if(clazz.isAnnotationPresent(Scope.class)){
                                //圆型的
                                Scope scope = clazz.getAnnotation(Scope.class);
                                String value = scope.value();
                                beanDefinition.setScope(value);
                            }else {
                                //单例的
                                beanDefinition.setScope("singleton");
                            }
                            beanDefinitionMap.put(beanName,beanDefinition);
                         //   System.out.println(clazz);
                        }
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InstantiationException e) {
                        e.printStackTrace();
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }

                }
            }

         //   System.out.println(path);
        }
    }


    //通过bean名称获取bean对象
    public Object getBean(String beanName){

        if(!beanDefinitionMap.containsKey(beanName)){
                throw new NullPointerException();
        }

        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if(beanDefinition.getScope().equals("singleton")){
            Object singletonBean = singleObjects.get(beanName);
            if(singletonBean== null){
                singletonBean = createBean(beanName, beanDefinition);
                singleObjects.put(beanName,singletonBean);
            }
            return singletonBean;
        }else {
            //原型的
            Object prototypeBean = createBean(beanName, beanDefinition);
            return prototypeBean;
        }
    }
}

定义注解@Autowired @Component @Scope @ComponentScan

java 复制代码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {
    String value() default "";
}







@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
    String value() default "";
}




@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
    String value() default "";
}





@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
    String value() default "";
}

定义后置处理器BeanPostProcessor,用于初始化

java 复制代码
public interface BeanPostProcessor {


    default Object postProcessBeforeInitialization(Object bean, String beanName)  {
        return bean;
    }


    default Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}

定义ZSJBeanPostProcessor实现BeanPostProcesso

java 复制代码
@Component
public class ZSJBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {

        if(beanName.equals("userService")){
            Object proxyInstance = Proxy.newProxyInstance(ZSJBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //切面
                    System.out.println("切面逻辑");

                    return method.invoke(bean,args);
                }
            });
            return proxyInstance;
        }


        return bean;
    }
}

定义初始化接口InitializingBean

java 复制代码
public interface InitializingBean {
    void afterPropertiesSet();
}

定义普通的类(可实例化成单例bean)

java 复制代码
@Component("userService")
@Scope("singleton")
//public class UserService implements InitializingBean {
public class UserService implements UserInterface {

    @Autowired
    private OrderService orderService;



     @ZSanValue("zhangsan")
    private String user;

    //圆型bean 表示多例bean
    public void test(){
        System.out.println(orderService);
    }

//    @Override
//    public void afterPropertiesSet() {
//        System.out.println("初始化");
//    }
}

定义普通的类(可实例化成原型bean)

@Component("orderService")
@Scope("prototype")
public class OrderService {

    //圆型bean 表示多例bean
    public void test(){
        System.out.println("hello");
    }
}

定义启动类main

public class Test {
    public static void main(String[] args) {

        //非懒加载的单例bean
//        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//        UserService userService = (UserService)context.getBean("userService");
//
//        userService.test();


        ZSJApplicationContext context = new ZSJApplicationContext(AppConfig.class);
       UserInterface userService = (UserInterface)context.getBean("userService");
        userService.test();

  //      System.out.println(context.getBean("userService"));
//        System.out.println(context.getBean("userService"));
//        System.out.println(context.getBean("userService"));
//        System.out.println(context.getBean("orderService"));
//        System.out.println(context.getBean("orderService"));
//        System.out.println(context.getBean("orderService"));


//        AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(context);
//        reader.register(User.class);
//        System.out.println(context.getBean("user"));


        StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor();
        propertyEditor.setAsText("1");

        User value =new User();
        System.out.println(value);



    }
}

BeanPostProcesso扩展使用方法

自定义注解@ZSanValue

java 复制代码
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ZSanValue {
    String value() default "";
}

使用注解时,将注解的值赋给属性:如

java 复制代码
@ZSanValue("zhangsan")
private String user;

实现后置处理器,并执行初始化前的操作,将自定义的注解值进行属性赋值

java 复制代码
@Component
public class ZSanValueBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {

        for (Field field : bean.getClass().getDeclaredFields()) {
            if(field.isAnnotationPresent(ZSanValue.class)){
                field.setAccessible(true);
                try {
                    field.set(bean,field.getAnnotation(ZSanValue.class).value());
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }


        return bean;
    }
}

回调方法使用BeanNameAware

定义回调接口

java 复制代码
public interface BeanNameAware {
    
    void setBeanName(String name);
}

则实现类需要实现BeanNameAware接口

java 复制代码
@Component("userService")
@Scope("singleton")
//public class UserService implements InitializingBean {
public class UserService implements UserInterface,BeanNameAware {

    @Autowired
    private OrderService orderService;

    @ZSanValue("zhangsan")
    private String user;


    private String beanName;


    //圆型bean 表示多例bean
    public void test(){
        System.out.println(orderService);
    }

    @Override
    public void setBeanName(String name) {
       this.beanName=name;
    }

//    @Override
//    public void afterPropertiesSet() {
//        System.out.println("初始化");
//    }
}
相关推荐
向上的车轮6 分钟前
Django学习笔记二:数据库操作详解
数据库·django
编程老船长16 分钟前
第26章 Java操作Mongodb实现数据持久化
数据库·后端·mongodb
全栈师1 小时前
SQL Server中关于个性化需求批量删除表的做法
数据库·oracle
Data 3171 小时前
Hive数仓操作(十七)
大数据·数据库·数据仓库·hive·hadoop
BergerLee2 小时前
对不经常变动的数据集合添加Redis缓存
数据库·redis·缓存
程序员大金2 小时前
基于SpringBoot+Vue+MySQL的装修公司管理系统
vue.js·spring boot·mysql
gorgor在码农2 小时前
Mysql 索引底层数据结构和算法
数据结构·数据库·mysql
-seventy-2 小时前
SQL语句 (MySQL)
sql·mysql
bug菌¹2 小时前
滚雪球学Oracle[6.2讲]:Data Guard与灾难恢复
数据库·oracle·data·灾难恢复·guard
一般路过糸.2 小时前
MySQL数据库——索引
数据库·mysql