30个类提炼Spring-SpringIOC/DI
1.从Servlet到ApplicationContext
public interface STBeanFactory {
/**
* 根据beanName从IOC容器获得一个实例bean
* @param beanName
* @return
*/
Object getBean (String beanName );
}
public interface STFactoryBean {
}
public class STApplicationContext extends STDefaultListableBeanFactory implements STBeanFactory {
private String [] configLocations ;
private STBeanDefinitionReader reader ;
public STApplicationContext (String ... configLocations ) {
this .configLocations = configLocations ;
refresh ();
}
@ Override
public void refresh () {
// 1.定位,定位配置文件
reader = new STBeanDefinitionReader (configLocations );
// 2.加载配置文件,扫描相关的类,把它们封装成BeanDefinition
List <STBeanDefinition > beanDefinitionList = reader .loadBeanDefinitions ();
// 3.注册,把配置信息放到容器里面(伪IOC容器)
doRegistryBeanDefinition (beanDefinitionList );
// 4.把不是延迟加载的类,提前初始化
doAutowired ();
}
// 只处理非延时加载的情况
private void doAutowired () {
for (Map .Entry <String , STBeanDefinition > beanDefinitionEntry : super .beanDefinitionMap .entrySet ()) {
String beanName = beanDefinitionEntry .getKey ();
if (!beanDefinitionEntry .getValue ().isLazyInit ()) {
getBean (beanName );
}
}
}
private void doRegistryBeanDefinition (List <STBeanDefinition > beanDefinitionList ) {
for (STBeanDefinition beanDefinition : beanDefinitionList ) {
this .beanDefinitionMap .put (beanDefinition .getFactoryBeanName (), beanDefinition );
}
}
@ Override
public Object getBean (String beanName ) {
// 1.初始化
instantiateBean (beanName , new STBeanDefinition ());
// 2.注入
populateBean (beanName , new STBeanDefinition (), new STBeanWrapper ());
return null ;
}
private void populateBean (String beanName , STBeanDefinition stBeanDefinition , STBeanWrapper stBeanWrapper ) {
}
private void instantiateBean (String beanName , STBeanDefinition stBeanDefinition ) {
}
}
AbstractApplicationContext
public abstract class STAbstractApplicationContext {
/**
* 受保护,只提供子类重写
*/
protected void refresh (){}
}
DefaultListableBeanFactory
/** Map of bean definition objects, keyed by bean name */
//存储注册信息的BeanDefinition
protected final Map <String , STBeanDefinition > beanDefinitionMap = new ConcurrentHashMap <>(256 );
public class STBeanDefinition {
private String beanClassName ;
private boolean lazyInit = false ;
private String factoryBeanName ;
}
public interface STApplicationContextAware {
void setApplicationContext (STApplicationContext applicationContext );
}
public class STBeanDefinitionReader {
private Properties config = new Properties ();
// 固定配置文件中的key
private final String SCAN_PACKAGE = "scanPackage" ;
private List <String > registryBeanClasses = new ArrayList <>();
public STBeanDefinitionReader (String ... locations ) {
// 通过URL定位找到其对应的文件,然后转为文件流
InputStream inputStream = this .getClass ().getClassLoader ().getResourceAsStream (locations [0 ].replace ("classpath" , "" ));
try {
config .load (inputStream );
} catch (IOException e ) {
e .printStackTrace ();
} finally {
if (null != inputStream ) {
try {
inputStream .close ();
} catch (IOException e ) {
e .printStackTrace ();
}
}
}
doScanner (config .getProperty (SCAN_PACKAGE ));
}
private void doScanner (String scanPackage ) {
// 转为文件路径,实际上把.换成/就可以了
URL url = this .getClass ().getClassLoader ().getResource ("/" + scanPackage .replaceAll ("\\ ." , "/" ));
File classPath = new File (url .getFile ());
for (File file : classPath .listFiles ()) {
if (file .isDirectory ()) {
doScanner (scanPackage + "." + file );
} else {
if (file .getName ().endsWith (".class" )) {
continue ;
}
String className = (scanPackage + "." + file .getName ().replace (".class" , "" ));
registryBeanClasses .add (className );
}
}
}
public Properties getConfig () {
return this .config ;
}
// 把配置文件中扫描的所有配置信息转换为STBeanDefinition对象,以便IOC操作方便
public List <STBeanDefinition > loadBeanDefinitions (String ... locations ) {
List <STBeanDefinition > result = new ArrayList <>();
for (String className : registryBeanClasses ) {
STBeanDefinition beanDefinition = doCreateBeanDefinition (className );
if (null == beanDefinition ) { continue ; }
result .add (beanDefinition );
}
return result ;
}
// 把没一个配置信息解析称一个BeanDefinition
private STBeanDefinition doCreateBeanDefinition (String className ) {
try {
Class <?> beanClass = Class .forName (className );
// 有可能是一个接口,用他的实现类作为beanClassName
if (beanClass .isInterface ()) {
return null ;
}
STBeanDefinition stBeanDefinition = new STBeanDefinition ();
stBeanDefinition .setBeanClassName (className );
stBeanDefinition .setFactoryBeanName (beanClass .getSimpleName ());
return stBeanDefinition ;
} catch (Exception e ) {
}
return null ;
}
/**
* 默认不存在类名首字母小写的情况
* @param simpleName
* @return
*/
private String toLowerFirstCase (String simpleName ) {
char [] chars = simpleName .toCharArray ();
// 之所以加32,是因为大小写字母恶ASCII码相差32
// 而且大写字母的ASCII码小于小写字母的ASCII码
// 在Java中,对char作算学运算,实际上就是对ASCII码做运算
chars [0 ] += 32 ;
return String .valueOf (chars );
}
}
public class STBeanWrapper {
/**
* Return the bean instance wrapped by this object.
*/
public Object getWrappedInstance () {
return null ;
}
/**
* Return the type of the wrapped bean instance.
*/
public Class <?> getWrappedClass () {
return null ;
}
}