Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。也是几乎所有Java工作者必须要掌握的框架之一,其优秀的设计思想以及其代码实现上的艺术也是我们需要掌握的。要学习Spring,除了在我们的项目中使用之外,也需要对它的源码进行研读,但是Spring的实现涵盖的知识很多,在加上其中的类的数量也是非常的多,在我们阅读源码时可能会在几十个类之间穿插阅读,很有可能一不小心就导致思维混乱。有鉴于此,我这里先对Spring中的几个重要的模块进行一个手动的简易实现,一是熟悉这些模块的原理,同时也是仿造Spring中的结构来对后面阅读源码打下基础。
IOC(Inversion of Control)
Inversion of Control即控制反转,其意思是将我们之前由客户端代码来创建的对象交由IOC容器来进行控制,对象的创建,初始化以及后面的管理都由IOC完成。
IOC的好处
解耦:IOC的出现解决了类于类之间的耦合,我们在Web开发的Servlet时代,如果一个Servlet需要依赖另一个类的某些实现,那么我们需要在当前类对依赖的类进行创建和初始化,如果其他类也依赖了这个类,那也需要进行创建和初始化,而交给了IOC来管理的话,那么在需要的时候只需向IOC进行申请,而不需要重复的创建和初始化。当然,IOC也允许每次都重新创建一个新的对象。
方便与AOP进行配合:AOP也是一个使用十分频繁的功能,通过IOC可以十分方便的与AOP进行配合。
IOC中设计的设计模式
工厂模式。IOC容器来负责创建管理类实例对象,在需要时向IOC进行申请,从IOC中获取。所以IOC容器也称为bean工厂。
工厂模式是一种比较简单易懂的设计模式,这里就不在介绍了。
而要自己写出一个IOC容器是很难以实现的,所以这里就只是仿照IOC的源码,将主线流程梳理,模拟。
首先第一步就是要梳理好IOC源码中所涉及到几大接口、父类与他们各自的职责
IOC的入口就是context容器,不管是使用注解的方式还是xml的方式,他们的顶级父类就是AbstractApplicationContext,来完成初始化工厂与IOC容器所需要的bean对象,而在创建容器实现类的时候又进行了bean扫描,bean注册,bean的获取与创建几个步骤。
1、bean扫描
类:BeanDefinitionScanner
方法:scan();
2、bean注册
类: BeanDefinitionRegistry
方法:registerBeanDefinition();
3、容器
类:AbstractApplicationContext
方法:refresh(),finish(),close()
4、bean的获取和创建
类:BeanFactory
方法:getBean() ,createBean() ,registry();
AbstractApplicationContext与AnnotationConfigApplicationContext
//实现了BeanDefinitionRegistry接口,并重写其中的注册方法,在创建容器时在构造方法中调用
public class AbstractApplicationContext implements BeanDefinitionRegistry {
public ConfigurableListableBeanFactory beanFactory;
public AbstractApplicationContext(){
//创建bean工厂
beanFactory=new ConfigurableListableBeanFactory();
}
public void registryBeanDefinition(String beanName, BeanDefinition beanDefinition) {
beanFactory.registryBeanDefinition(beanName,beanDefinition);
}
public void refresh(){
// 获取bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 工厂信息初始化完成后,开始创建单例非懒加载的bean
finishBeanFactoryInitialization(beanFactory);
}
//完成工厂初始化
private void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//设置数据格式转换器
//添加环境变量解析器到容器中
//初始所有需要进行代码植入的对象LoadTimeWeaverAware
//设置临时类加载器
//锁定所有bean的配置信息,此后不允许再进行改变
// 实例化所有非懒加载的bean对象
beanFactory.preInstantiateSingletons();
}
private ConfigurableListableBeanFactory obtainFreshBeanFactory() {
return this.beanFactory;
}
}
//实现了BeanFactory接口,实现了getBean方法,创建容器后获取bean对象使用
//继承AbstractApplicationContext,创建容器后刷新容器并创建需要注册的bean对象
public class AnnotationConfigApplicationContext extends AbstractApplicationContext implements BeanFactory {
private BeanDefinitionScanner beanDefinitionScanner;
AnnotationConfigApplicationContext() {
//创建扫描器
beanDefinitionScanner = new BeanDefinitionScanner(this);
}
public AnnotationConfigApplicationContext(String basePackge) {
//先实例化beanFactory,创建一个beanScanner
this();
//扫描
beanDefinitionScanner.scan(basePackge);
//刷新容器
refresh();
}
public Object getBean(String beanName) {
return beanFactory.getBean(beanName);
}
}
BeanDefinitionScanner扫描器
在创建容器时先创建扫描器,将扫描到的bean信息注册到工厂。
public class BeanDefinitionScanner {
private BeanDefinitionRegistry registry;
private Set<Class<?>> beanClass = new HashSet<Class<?>>();
public BeanDefinitionScanner(BeanDefinitionRegistry registry) {
this.registry = registry;
}
public void scan(String basePackge) {
doScan(basePackge);
}
private void doScan(String basePackge) {
//扫描带有@Component注解的class
Set<BeanDefinition> beanDefinitions = findComponent(basePackge);
//解析懒加载、是否单例属性
for (BeanDefinition beanDefinition : beanDefinitions) {
beanDefinition.setLazy(false);
beanDefinition.setSigle(true);
//注册到容器
registry.registryBeanDefinition(beanDefinition.getBeanName(), beanDefinition);
}
}
private Set<BeanDefinition> findComponent(String basePackge) {
Set<BeanDefinition> beanDefinitions = new HashSet<BeanDefinition>();
//加载所有class
loadClass(basePackge);
//解析带有@Component注解的class
for (Class cls : beanClass) {
if (cls.isAnnotationPresent(ArdComponent.class) || cls.isAnnotationPresent(ArdService.class)) {
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setBeanClass(cls);
beanDefinition.setBeanName(BeanNameUtil.getBeanName(cls.getSimpleName()));
beanDefinitions.add(beanDefinition);
}
}
return beanDefinitions;
}
private void loadClass(String scanPath) {
try {
String filePath = scanPath.replace(".", "/");
URL url = this.getClass().getClassLoader().getResource(filePath);
File file = new File(url.toURI());
doLoadClass(file, filePath);
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
private void doLoadClass(File file, String scanPath) {
//文件夹
if (file.isDirectory()) {
File[] fileList = file.listFiles();
for (File f : fileList) {
doLoadClass(f, scanPath + "/" + f.getName());
}
}
//文件
if (file.getName().indexOf(".class") > 0) {
try {
//文件夹格式转为包格式
String packgePath = scanPath.replace("/", ".");
Class cls = Class.forName(packgePath.replace(".class", ""));
beanClass.add(cls);
} catch (ClassNotFoundException e) {
System.out.println("解析class错误。。。。");
e.printStackTrace();
}
}
}
}
BeanDefinitionRegistry注册
Bean信息的注册接口,由bean工厂实现,将扫描到bean信息存入容器中生成bean对象时使用。
public interface BeanDefinitionRegistry {
public void registryBeanDefinition(String beanName, BeanDefinition beanDefinition);
}
BeanFactory与ConfigurableListableBeanFactory工厂接口与工厂实现类
为容器提供getBean()方法,实现BeanDefinitionRegistry注册接口,实现bean的注册与创建bean放入核心容器中。
//提供获取bean的方法。
public interface BeanFactory {
public Object getBean(String beanName);
}
//实现了注册接口,为核心容器提供了getBean实现接口与注册bean信息和生成bean的方法。
//注:在生成bean时使用三级缓存的方式解决了循环依赖的问题。
public class ConfigurableListableBeanFactory implements BeanDefinitionRegistry,BeanFactory{
private ConcurrentHashMap<String,BeanDefinition> BeanDefinitionMap=new ConcurrentHashMap();
//缓存所有已经创建完成的单例bean
private ConcurrentHashMap<String,Object> singletonObjects=new ConcurrentHashMap();
//缓存正在创建的bean
private ConcurrentHashMap<String,Object> singletonsCurrentlyInCreation=new ConcurrentHashMap();
//缓存所正准备创建的bean
private ConcurrentHashMap<String,Object> singletonFactories=new ConcurrentHashMap();
//保存所有BeanPostProcessor
private Set<BeanPostProcessor> beanPostProcessorSet=new HashSet<BeanPostProcessor>();
public void registryBeanDefinition(String beanName, BeanDefinition beanDefinition) {
BeanDefinitionMap.put(beanName,beanDefinition);
}
/**
* 实例化所有单例非懒加载的bean
*/
public void preInstantiateSingletons() {
//获取所有bean的定义信息
// 遍历初始化所有 非来加载并且为单例的bean信息
//调用getBean()进行bean的实例化
for(BeanDefinition beanDefinition:BeanDefinitionMap.values()){
//如果非懒加载并且为单例,创建bean
if(!beanDefinition.isLazy()&&beanDefinition.isSigle()){
getBean(beanDefinition.getBeanName());
}
}
}
public Object getBean(String beanName) {
Object object= doGetBean( beanName);
if(object instanceof BeanPostProcessor){
beanPostProcessorSet.add((BeanPostProcessor)object);
}
return object;
}
/**
* 获取bean
* @param beanName
* @return
*/
private Object doGetBean(String beanName) {
//从缓存获取
if(singletonObjects.containsKey(beanName)){
return singletonObjects.get(beanName);
}
//缓存没有就创建
return createBean(beanName);
}
private Object createBean(String beanName) {
//确保已经解析了bean的定义信息,没有的话则重新创建bean的定义信息
//准备需要overrides覆盖的方法
// ==BeanPostProcessorsBeforeInstantiation 的扩展实现,返回代理对象
//====正式开始创建bean
return doCreateBean(beanName);
}
private Object doCreateBean(String beanName) {
//先验证循环依赖
if(singletonsCurrentlyInCreation.containsKey(beanName)||singletonFactories.containsKey(beanName)){
System.out.println("可能存在循环依赖"+beanName);
throw new RuntimeException("可能存在循环依赖");
}
//标记正准备创建,放到三级缓存
singletonFactories.put(beanName,"");
//创建对象实例
BeanWrapper beanWrapper=createInstance(beanName);
//标记对象正在创建中 放到二级缓存
singletonsCurrentlyInCreation.put(beanName,beanWrapper.getBeanInstance());
singletonFactories.remove(beanName);
//属性注入
populateBean(beanWrapper);
Object expactIntance= initializeBean(beanName,beanWrapper);
//放到一级缓存里
singletonObjects.put(beanName,expactIntance);
singletonsCurrentlyInCreation.remove(beanName);
return expactIntance;
}
private Object initializeBean(String beanName,BeanWrapper beanWrapper) {
Object object=beanWrapper.getBeanInstance();
//获取所有实现了beanPostProcessor的接口
for(BeanPostProcessor beanPostProcessor:this.beanPostProcessorSet){
object=beanPostProcessor.postProcessBeforeInitialization(beanWrapper.getBeanInstance(),beanName);
}
//先执行beanPostProcessor postProcessBeforeInitialization
//在执行init
System.out.println("调用 init方法.....");
for(BeanPostProcessor beanPostProcessor:this.beanPostProcessorSet){
object=beanPostProcessor.postProcessAfterInitialization(beanWrapper.getBeanInstance(),beanName);
}
return object;
}
/**
* 依赖注入
*/
private void populateBean(BeanWrapper beanWrapper) {
//1属性赋值
//2依赖注入
//2.1获取对象属性中带有@ArdAutowired的属性
Field[] fields=beanWrapper.getBeanInstance().getClass().getDeclaredFields();
for(Field field:fields){
if(field.isAnnotationPresent(ArdAutowired.class)){
//获取属性bean的名称
String beanName= BeanNameUtil.getBeanName(field.getType().getSimpleName());
Object populateBeanInstance=null;
//看一级和二级缓存有没有
if(singletonObjects.containsKey(beanName)){
populateBeanInstance=singletonObjects.get(beanName);
}
if(populateBeanInstance==null&&singletonsCurrentlyInCreation.containsKey(beanName)){
populateBeanInstance=singletonsCurrentlyInCreation.get(beanName);
}
if(populateBeanInstance==null){
populateBeanInstance=getBean(beanName);
}
//属性赋值
beanWrapper.setBeanProperty(beanName,populateBeanInstance);
}
}
//没有就调用getBean();
//给属性赋值
}
/**
* 创建bean
* @param beanName
* @return
*/
private BeanWrapper createInstance(String beanName) {
try {
BeanDefinition beanDefinition=BeanDefinitionMap.get(beanName);
Object object= beanDefinition.getBeanClass().newInstance();
BeanWrapper beanWrapper=new BeanWrapper();
beanWrapper.setBeanInstance(object);
beanWrapper.setBeanClass(beanDefinition.getBeanClass());
return beanWrapper;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
//解析bean时的工具类,封装通用方法
public class BeanNameUtil {
//解析首字母小写的bean
public static String getBeanName(String beanName){
return beanName.substring(0,1).toLowerCase()+beanName.substring(1,beanName.length());
}
}
BeanDefinition与BeanWrapper实体类
封装bean注册时的信息实体类与创建bean时的实例。
//封装注册bean时所需的参数,初始化工厂时使用。
@Data
public class BeanDefinition {
//bean名称
private String beanName;
//bean的class
private Class<?> beanClass;
//是否单例
private boolean isSigle;
//是否懒加载
private boolean isLazy;
}
//封装已实例化的bean与字节对象。提供设置对象属性的方法,使用反射的方式。
@Data
public class BeanWrapper {
private Object beanInstance;
private Class<?> beanClass;
/**
* 设置对象属性
* @param propertyName
* @param object
*/
public void setBeanProperty(String propertyName,Object object){
try {
//获得属性
Field[] beanFile=beanClass.getDeclaredFields();
//匹配属性名,并设值
for(Field file:beanFile){
file.setAccessible(true);
if( file.getName().equals(propertyName)){
file.set(beanInstance,object);
}
}
} catch (IllegalAccessException e) {
System.out.println("设置属性名失败....");
e.printStackTrace();
}
}
}
@XXXAutowired
@XXXComponent
@XXXService
自定义依赖注入注解与标记需要放入容器创建bean的注解。
注:@XXXService将继承@XXXComponent注解,在扫描器进行扫描时只会扫描标记有XXXComponent注解的类。
UserDao
UserService 实体类
需要创建bean的实体类,service层依赖注入dao层对象。
TestAnnotationConfigApplicationContext
创建核心容器,测试仿IOC代码。
public class TestAnnotationConfigApplicationContext{
public static void main(String[] args) {
AnnotationConfigApplicationContext configApplicationContext=new AnnotationConfigApplicationContext("com.test.scanPackage");
UserService userService=(UserService) configApplicationContext.getBean("userService");
userService.getUserInfo("testSuccess");
}
}
扩展:BeanPostProcessor
创建bean时的后置处理器接口,实现该接口可以在工厂初始化bean后更改bean的属性等处理。
//提供前置处理与后置处理方法。
public interface BeanPostProcessor {
//前置处理
public Object postProcessBeforeInitialization(Object bean, String beanName);
//后置处理
public Object postProcessAfterInitialization(Object bean, String beanName);
}
//每次初始化bean时都会将所有的Proccessor处理器全部执行一次。
@XXXComponent
public class MyBeanPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println(beanName);
System.out.println("MyBeanPostProcessor before");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println(beanName);
System.out.println("MyBeanPostProcessor after");
return bean;
}
}