软件编程
位置:首页>> 软件编程>> java编程>> 手把手带你实现一个萌芽版的Spring容器

手把手带你实现一个萌芽版的Spring容器

作者:三分恶  发布时间:2023-03-10 15:45:44 

标签:Java,Spring,容器

从什么是IOC开始?

Spring——春天,Java编程世界的春天是由一位音乐家——Rod Johnson带来的。

Rod Johnson先后编写了两本巨著《Expert One-on-One J2EE Design and Development》、《Expert One-on-One J2EE Development without EJB》,拉起了挑战正统Java EE框架EJB的大旗。

手把手带你实现一个萌芽版的Spring容器

Rod Johnson不仅是一名旗手,更是开发了Spring这一轻量级框架,像一名勇敢的龙骑兵一样,对EJB发动了冲锋,并最终战胜了EJB,让Spring成为Java EE事实上的标准。

手把手带你实现一个萌芽版的Spring容器

Spring的两大内核分别是IOC和AOP,其中最最核心的是IOC。

所谓的IOC(控制反转):就是由容器来负责控制对象的生命周期和对象间的关系。以前是我们想要什么,就自己创建什么,现在是我们需要什么,容器就给我们送来什么。

手把手带你实现一个萌芽版的Spring容器

也就是说,控制对象生命周期的不再是引用它的对象,而是容器。对具体对象,以前是它控制其它对象,现在所有对象都被容器控制,所以这就叫控制反转。

手把手带你实现一个萌芽版的Spring容器

也许你还听到另外一个概念DI(依赖注入),它指的是容器在实例化对象的时候把它依赖的类注入给它,我们也可以认为,DI是IOC的补充和实现。

工厂和Spring容器

Spring是一个成熟的框架,为了满足扩展性、实现各种功能,所以它的实现如同枝节交错的大树一样,现在让我们把视线从Spring本身移开,来看看一个萌芽版的Spring容器怎么实现。

Spring的IOC本质就是一个大工厂,我们想想一个工厂是怎么运行的呢?

手把手带你实现一个萌芽版的Spring容器

生产产品:一个工厂最核心的功能就是生产产品。在Spring里,不用Bean自己来实例化,而是交给Spring,应该怎么实现呢?——答案毫无疑问,反射。

那么这个厂子的生产管理是怎么做的?你应该也知道——工厂模式。

库存产品:工厂一般都是有库房的,用来库存产品,毕竟生产的产品不能立马就拉走。Spring我们都知道是一个容器,这个容器里存的就是对象,不能每次来取对象,都得现场来反射创建对象,得把创建出的对象存起来。

订单处理:还有最重要的一点,工厂根据什么来提 * 品呢?订单。这些订单可能五花八门,有线上签签的、有到工厂签的、还有工厂销售上门签的……最后经过处理,指导工厂的出货。

在Spring里,也有这样的订单,它就是我们bean的定义和依赖关系,可以是xml形式,也可以是我们最熟悉的注解形式。

那对应我们的萌芽版的Spring容器是什么样的呢?

手把手带你实现一个萌芽版的Spring容器

订单:Bean定义

Bean可以通过一个配置文件定义,我们会把它解析成一个类型。

手把手带你实现一个萌芽版的Spring容器

  • beans.properties

为了偷懒,这里直接用了最方便解析的properties,用一个<key,value>类型的配置来代表Bean的定义,其中key是beanName,value是class

userDao:cn.fighter3.bean.UserDao

  • BeanDefinition.java

bean定义类,配置文件中bean定义对应的实体


public class BeanDefinition {

private String beanName;

private Class beanClass;
    //省略getter、setter  
}

获取订单:资源加载

接下订单之后,就要由销售向生产部门交接,让生产部门知道商品的规格、数量之类。

资源加载器,就是来完成这个工作的,由它来完成配置文件中配置的加载。


public class ResourceLoader {

public static Map<String, BeanDefinition> getResource() {
       Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>(16);
       Properties properties = new Properties();
       try {
           InputStream inputStream = ResourceLoader.class.getResourceAsStream("/beans.properties");
           properties.load(inputStream);
           Iterator<String> it = properties.stringPropertyNames().iterator();
           while (it.hasNext()) {
               String key = it.next();
               String className = properties.getProperty(key);
               BeanDefinition beanDefinition = new BeanDefinition();
               beanDefinition.setBeanName(key);
               Class clazz = Class.forName(className);
               beanDefinition.setBeanClass(clazz);
               beanDefinitionMap.put(key, beanDefinition);
           }
           inputStream.close();
       } catch (IOException | ClassNotFoundException e) {
           e.printStackTrace();
       }
       return beanDefinitionMap;
   }

}

订单分配:Bean注册

对象注册器,这里用于单例bean的缓存,我们大幅简化,默认所有bean都是单例的。可以看到所谓单例注册,也很简单,不过是往HashMap里存对象。


public class BeanRegister {

//单例Bean缓存
   private Map<String, Object> singletonMap = new HashMap<>(32);

/**
    * 获取单例Bean
    *
    * @param beanName bean名称
    * @return
    */
   public Object getSingletonBean(String beanName) {
       return singletonMap.get(beanName);
   }

/**
    * 注册单例bean
    *
    * @param beanName
    * @param bean
    */
   public void registerSingletonBean(String beanName, Object bean) {
       if (singletonMap.containsKey(beanName)) {
           return;
       }
       singletonMap.put(beanName, bean);
   }

}

生产车间:对象工厂

来源:https://blog.csdn.net/sinat_40770656/article/details/123217592

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com