手写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文件内的配置。