手写MVC初体验之容器基础(二)

手写MVC初体验之容器基础(二)

第一版是DispatcherServlet中实现容器。

第二版需要从DispatcherServlet中抽离出Ioc和Bean的封装作为ApplicationContext、BeanDefinition、BeanWrapper,然后实现Spring的三级缓存机制。将配置读取功能封装成BeanDefinitionReader。

同时在DispatcherServlet中将method封装成Handler。

容器文件结构:

1. 抽离ApplicationContext

抽离ApplicationContext就是将DispatcherServlet中的前四个步骤放入ApplicationContext中执行

  • 读取配置文件
  • 扫描类
  • 初始化Ioc容器
  • 依赖注入
package org.framework.spring.v1.context.core.impl;

import org.framework.spring.v1.context.bean.support.autowire.BeanPostProcessor;
import org.framework.spring.v1.context.bean.support.autowire.factory.BeanPostProcessorFactory;
import org.framework.spring.v1.context.bean.support.reader.BeanDefinitionReader;
import org.framework.spring.v1.context.bean.support.reader.factory.BeanDefinitionReaderFactory;
import org.framework.spring.v1.context.bean.support.registry.BeanDefinitionRegistry;
import org.framework.spring.v1.context.bean.support.wrapper.BeanWrapperProcess;
import org.framework.spring.v1.context.bean.support.wrapper.factory.BeanWrapperProcessFactory;
import org.framework.spring.v1.context.core.ApplicationContext;

import java.util.Map;


/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/6/18 21:43
 */

public class AnnotationApplicationContext implements ApplicationContext {

    private BeanDefinitionReader reader ;

    private BeanDefinitionRegistry registry ;

    private BeanWrapperProcess process ;

    private BeanPostProcessor beanFactory ;

    /**
     * 传入的是application.properties
     * @param contextConfiguration
     */
    public AnnotationApplicationContext(String contextConfiguration) {

        //通过reader加载配置文件
        this.reader = BeanDefinitionReaderFactory.getAnnotation(contextConfiguration) ;
        //注册 beanDefinitionMap
        //一级缓存——beanName->BeanDefinition 交由reader下面的registry处理
        this.registry = this.reader.getRegistry() ;
        //二级缓存——BeanDefinition->BeanWrapper 交由process处理
        this.process = BeanWrapperProcessFactory.getBeanWrapperProcess(this.registry) ;
        //三级缓存——BeanWrapper->Bean
        this.beanFactory = BeanPostProcessorFactory.getAutowireCapable(this.process) ;
    }

    @Override
    public Map<String, Object> getIoc() {
        return this.beanFactory.getIoc() ;
    }

    @Override
    public void registerBean(String className) {
        //首先是registerClassName列表中

        //registry的BeanDefinition

        //process的BeanDefinition

        //beanFactory的Object

    }

    @Override
    public void removeBean(String beanName) {
        //首先是registerClassName列表中

        //registry的BeanDefinition

        //process的BeanDefinition

        //beanFactory的Object
    }

    @Override
    public int getIocCount() {
        return this.beanFactory.getBeanCount() ;
    }

    @Override
    public boolean isBeanExist(Object bean) {
        return this.beanFactory.isBeanExist(bean) ;
    }

    @Override
    public boolean isBeanNameExist(String beanName) {
        return this.beanFactory.isBeanNameExist(beanName) ;
    }

}

2. BeanDefinition、BeanWrapper的定义

2.1. AbstractRootBeanDefinition

package org.framework.spring.v1.context.bean.config.definition.abs;

import org.framework.spring.v1.context.bean.config.definition.RootBeanDefinition;

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/7/5 15:25
 */

public abstract class AbstractRootBeanDefinition implements RootBeanDefinition {

    /**
     * beanName
     * toLowerFirstAlp(getClass.getSimpleName)
     * 类名首字母小写
     */
    protected String factoryBeanName ;

    /**
     * className
     * getClass.getName()
     * 类路径
     * 为BeanWrapper的Class.forName做参数准备
     */
    protected String beanClassName ;

    /**
     * 实例化类型,暂时不实现
     */
    protected String scope ;

    public AbstractRootBeanDefinition(String factoryBeanName, String beanClassName, String scope) {
        this.factoryBeanName = factoryBeanName;
        this.beanClassName = beanClassName;
        this.scope = scope;
    }

    public AbstractRootBeanDefinition(){

    }
}

2.2. DefaultRootBeanDefinition

默认实现类

package org.framework.spring.v1.context.bean.config.definition.impl;

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/6/18 18:24
 */

import org.framework.spring.v1.context.bean.config.definition.abs.AbstractRootBeanDefinition;
import org.framework.spring.v1.tools.ScopeValue;

/**
 * bean的定义
 */
public class DefaultRootBeanDefinition extends AbstractRootBeanDefinition {


    public DefaultRootBeanDefinition(String factoryBeanName, String beanClassName) {
        this(factoryBeanName , beanClassName , ScopeValue.singleton) ;
    }

    public DefaultRootBeanDefinition(String factoryBeanName, String beanClassName, String scope) {
        super(factoryBeanName, beanClassName, scope);
    }

    public DefaultRootBeanDefinition(){

    }

    @Override
    public String getFactoryBeanName() {
        return this.factoryBeanName;
    }

    @Override
    public boolean isSingleton() {
        return this.scope.equals(ScopeValue.singleton) ;
    }

    @Override
    public String getScopeValue() {
        return this.scope ;
    }

    @Override
    public String getBeanClassName() {
        return this.beanClassName;
    }
}

BeanDefinition是封装了类路径和类名(接口路径和接口名)。BeanWrapper封装了类的实例(没有属性注入)和类的Class类。

3. BeanWrapper

默认实现的BeanWrapper

package org.framework.spring.v1.context.bean.config.wrapper.impl;

import org.framework.spring.v1.context.bean.config.wrapper.BeanWrapper;
import org.framework.spring.v1.tools.ScopeValue;

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/6/19 16:25
 */


public class DefaultBeanWrapper implements BeanWrapper {

    /**
     * 初始化的bean,但是没有被注入属性
     */
    private Object wrapperInstance ;

    /**
     * 实例对应的class类
     */
    private Class<?> wrapperClass ;

    private String scope ;

    public DefaultBeanWrapper(Object wrapperInstance , String scope) {
        this.wrapperInstance = wrapperInstance;
        this.wrapperClass = wrapperInstance.getClass() ;
        this.scope = scope ;
    }

    @Override
    public Object getWrapperInstance() {
        return wrapperInstance;
    }

    @Override
    public Class<?> getWrapperClass() {
        return wrapperClass;
    }

    @Override
    public String getScopeValue() {
        return this.scope ;
    }

    @Override
    public boolean isSingleton() {
        return this.scope.equals(ScopeValue.singleton);
    }
}

4. Resource

Resource代表着web.xml内属性配置的application.properties文件,将其转化为Properties

package org.framework.spring.v1.context.bean.config.resource.impl;

/**
 * @author gyh
 * @csdn https://blog.csdn.net/qq_40788718
 * @date 2020/6/28 18:13
 */

import org.framework.spring.v1.context.bean.config.resource.Resource;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * 获取包
 */
public class DefaultResource implements Resource {

    private Properties properties ;

    public DefaultResource(String config){
        this.properties = new Properties() ;
        doLoadConfig(config) ;
    }

    private void doLoadConfig(String config) {
        if ("".equals(config)){
            throw new IllegalArgumentException("Web Application need value of contextConfiguration in the web.xml") ;
        }
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(config) ;
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (null != inputStream){
                try {
                    //关闭输入流
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public String getProperty(String key){
        return this.properties.getProperty(key) ;
    }
}

5. 小结

到目前为止,针对于ApplicationContext需要的“静态资源类”设置完毕。

  • BeanDefinition组:将bean文件注册为类,并设置beanName。可以发现BeanDefinition包装的是给定文件夹下的所有类,包括没有注解@Component的类。
  • BeanWrapper组:将BeanDefinition转化为实例的包装类。
  • Resource组:包装application.properties文件内的配置。

猜你喜欢

转载自blog.csdn.net/qq_40788718/article/details/107307800