Spring IoC 主要是以下几个步骤。
- 初始化 IoC 容器。
- 读取配置文件。
- 将配置文件转换为容器识别对的数据结构(这个数据结构在Spring中叫做 BeanDefinition)
- 利用数据结构依次实例化相应的对象
- 注入对象之间的依赖关系
BeanFactory工厂类接口
public interface BeanFactory {
//根据类名获得bean
Object getBean(String beanName,BeanScope beanScope);
Object getBean(String name);
//根据类对象获得bean
Object getBean(Class<?> cls,BeanScope beanScope);
Object getBean(Class<?> cls);
//设置bean
void setBean(String name, Object obj);
void setBean(Class<?> cls, Object obj);
//刷新Bean工厂
void refresh()throws Exception;
//Bean工厂是否为空
boolean isEmpty();
}
BeanScope是bean的作用域常量
public enum BeanScope {
//单例模式,只有一个实例
//原型模式,每次通过容器getbean都会产生一个新的bean实例
SINGLETON,
PROTOTYPE
}
BeanDefinition(bean的定义类)
bean的各项属性
public interface BeanDefinition {
//获得类对象
Class<?> getBeanClass();
//设置类对象
void setBeanClass(Class<?> cls);
//获得作用域
BeanScope getScope();
//是否单例
boolean isSingleton();
//是否原型
boolean isPrototype();
//是否需要代理
boolean getIsProxy();
//设置是否需要代理
void setIsProxy(boolean isProxy);
//获得代理类
MyProxy getProxy();
//设置代理类
void setProxy(MyProxy myProxy);
//获得初始化方法名
String getInitMethodName();
}
BeanDefinitionRegistry
将bean的定义信息BeanDefinition注册到BeanDefinition容器中
这里的注册 Bean 是指将 Bean 定义成 BeanDefinition,之后放入 Spring 容器中,就是拆分的意思
我们常说的容器其实就是 Beanfactory 中的一个 Map,key 是 Bean 的名称,value 是 Bean 对应的 BeanDefinition
public class BeanDefinitionRegistry {
//BeanDefinition容器
private static Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
//将bean注册进容器(map)
public static void registryBeanDefinition(String beanName,BeanDefinition beanDefinition{
//判空
Objects.requireNonNull(beanName, "beanName 不能为空");
Objects.requireNonNull(beanDefinition, "beanDefinition 不能为空");
beanDefinitionMap.put(beanName, beanDefinition);
}
//根据类名className获取BeanDefinition
public static BeanDefinition getBeanDefinition(String className){
return beanDefinitionMap.get(className);
}
//判断BeanDefinition是否存在
public static boolean containsBeanDefinition(String className) {
return beanDefinitionMap.containsKey(className);
}
//获得BeanDefinition容器
public static Map<String,BeanDefinition> getBeanDefinitionMap() {
return beanDefinitionMap;
}
}
GenericBeanDefinition(用于标准bean定义)
public class GenericBeanDefinition implements BeanDefinition{
private Class<?> beanClass;
private BeanScope scope =BeanScope.SINGLETON;
private String initMethodName;
private boolean isProxy = false;
private MyProxy myProxy = null;
public void setBeanClass(Class<?> beanClass){
this.beanClass = beanClass;
}
public void setScope(BeanScope scope) {
this.scope = scope;
}
public void setInitMethodName(String initMethodName) {
this.initMethodName = initMethodName;
}
@Override
public Class<?> getBeanClass() {
return beanClass;
}
@Override
public BeanScope getScope() {
return scope;
}
@Override
public boolean isSingleton() {
return Objects.equals(scope,BeanScope.SINGLETON);
}
@Override
public boolean isPrototype() {
return Objects.equals(scope, BeanScope.PROTOTYPE);
}
@Override
public String getInitMethodName() {
return initMethodName;
}
@Override
public MyProxy getProxy() {
// TODO Auto-generated method stub
return myProxy;
}
@Override
public void setProxy(MyProxy myProxy) {
// TODO Auto-generated method stub
this.myProxy = myProxy;
}
@Override
public boolean getIsProxy() {
// TODO Auto-generated method stub
return isProxy;
}
@Override
public void setIsProxy(boolean isProxy) {
// TODO Auto-generated method stub
this.isProxy=isProxy;
}
}
实现bean工厂接口
public class DefaultBeanFactory implements BeanFactory {
//bean工厂单例
private static volatile DefaultBeanFactory instance = null;
//一级缓存Bean容器,IOC容器,直接从此处获取Bean
private static Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
//二级缓存,为了将完全地Bean和半成品的Bean分离,避免读取到不完整的Bean
private static Map<String,Object> earlySingletonObjects=new ConcurrentHashMap<>();
//三级缓存,值为一个对象工厂,可以返回实例对象
private static Map<String,ObjectFactory> singletonFactories=new ConcurrentHashMap<>();
//是否在创建中
private static Set<String> singletonsCurrennlyInCreation = new HashSet<>();
//Bean的注册信息BeanDefinition容器
private static Map<String, BeanDefinition> beanDefinitionMap = BeanDefinitionRegistry.getBeanDefinitionMap();
}
初始化bean
//初始化bean
static {
///获得被Component,Service,Controller注解的类对象集合
Set<Class<?>> beanClassSet = ClassSetHelper.getBeanClassSet();
if(beanClassSet!=null && !beanClassSet.isEmpty()) {
try {
for(Class<?> beanClass : beanClassSet) {
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
genericBeanDefinition.setBeanClass(beanClass);
BeanDefinitionRegistry.registryBeanDefinition(beanClass.getName(), genericBeanDefinition);
}
//注册配置的bean
getInstance().initConfigBean();
//注册其他所有的bean
} catch (Exception e) {
e.printStackTrace();
}
}
}
ClassSetHelper.getBeanClassSet()
//获得被Component,Service,Controller注解的类对象集合
public static Set<Class<?>> getBeanClassSet() {
Set<Class<?>> beanClassSet = new HashSet<Class<?>>();
beanClassSet.addAll(getServiceClassSet());
beanClassSet.addAll(getControllerClassSet());
beanClassSet.addAll(getComponentClassSet());
return beanClassSet;
}
获取单例bean工厂
public static DefaultBeanFactory getInstance(){
if (null == instance){
synchronized (DefaultBeanFactory.class){
if (null == instance){
instance=new DefaultBeanFactory();
return instance;
}
}
}
return instance;
}
根据类名获取bean
public Object getBean(String beanName) {
Object bean = null;
try {
bean=doGetBean(beanName,BeanScope.SINGLETON);
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}
根据类的class对象获取bean
public Object getBean(Class<?> cls) {
Object bean = null;
try {
bean=doGetBean(cls.getName(),BeanScope.SINGLETON);
} catch (Exception e) {
e.printStackTrace();
}
return bean;
}
其中doGetBean指从beanMap获取bean,不存在就实例一个
同时加入三级缓存
private Object doGetBean(String beanName,BeanScope beanScope) throws Exception {
Objects.requireNonNull(beanName, "beanName 不能为空");
//获取单例
Object bean = getSingleton(beanName);
if(bean != null) {
return bean;
}
//如果未获取到bean,且bean不在创建中,则置bean的状态为在创建中
if(!singletonsCurrennlyInCreation.contains(beanName)) {
singletonsCurrennlyInCreation.add(beanName);
}
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if(beanDefinition==null) {
throw new Exception("不存在 "+beanName+" 的定义");
}
//获得类对象
Class<?> beanClass = beanDefinition.getBeanClass();
//找到实现类
beanClass = findImplementClass(beanClass,null);
//判断是否需要代理,若需要则生成代理类
if(beanDefinition.getIsProxy() && beanDefinition.getProxy()!=null) {
MyProxy myProxy = beanDefinition.getProxy();
bean=myProxy.getProxy(beanClass);
}
else {
bean = beanClass.getDeclaredConstructor().newInstance();
}
//将实例化后,但未注入属性的bean,放入三级缓存中
final Object temp = bean;
singletonFactories.put(beanName, new ObjectFactory() {
@Override
public Object getObject(){
return temp;
}
});
//反射调用init方法(获得初始化方法名)
String initMethodName = beanDefinition.getInitMethodName();
if (initMethodName != null){
Method method = beanClass.getMethod(initMethodName, null);
//方法调用
method.invoke(bean,null);
}
//注入bean的属性
fieldInject(beanClass, bean, false);
//如果三级缓存存在bean,则拿出放入二级缓存中
if(singletonFactories.containsKey(beanName)) {
ObjectFactory factory = singletonFactories.get(beanName);
earlySingletonObjects.put(beanName, factory.getObject());
singletonFactories.remove(beanName);
}
//如果二级缓存存在bean,则拿出放入一级缓存中
if(earlySingletonObjects.containsKey(beanName)) {
bean = earlySingletonObjects.get(beanName);
singletonObjects.put(beanName, bean);
earlySingletonObjects.remove(beanName);
}
return bean;
}
设置bean
@Override
public void setBean(String beanName, Object obj) {
try {
Objects.requireNonNull(beanName, "beanName 不能为空");
singletonObjects.put(beanName, obj);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
@Override
public void setBean(Class<?> cls, Object obj) {
this.setBean(cls.getName(), obj);
}
可以建立一个ClassSetHelper来扫描有某注解的类,并放进集合
//获取基础包名下直接或间接带有某注解的所有类
public static Set<Class<?>> getClassSetByInheritedAnnotation(Class<? extends Annotation> present){
Set<Class<?>> classSet = new HashSet<Class<?>>();
for (Class<?> cls : CLASS_SET) {
if(isAnnoPresent(cls,present)){
classSet.add(cls);
}
}
return classSet;
}
例如注入@Configuration中配置bean
private void initConfigBean() throws Exception {
Set<Class<?>> configClassSet = ClassSetHelper.getClassSetByInheritedAnnotation(Configuration.class);
if(configClassSet==null || configClassSet.isEmpty()) {
return;
}
for(Class<?> configClass : configClassSet) {
//注册Configuration
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
genericBeanDefinition.setBeanClass(configClass);
BeanDefinitionRegistry.registryBeanDefinition(configClass.getName(), genericBeanDefinition);
Object configBean = getBean(configClass);
Method[] methods = configClass.getDeclaredMethods();
for(Method method:methods) {
if(method.isAnnotationPresent(Bean.class)) {
Class<?> returnClass = method.getReturnType();
Object bean = method.invoke(configBean);
String keyName = returnClass.getName();
singletonObjects.put(keyName, bean);
System.out.println("成功注入"+configClass.getName()+" 中的 "+returnClass.getName());
}
}
singletonObjects.remove(configClass.getName());
}
}
自定义注解
例如@Value
@Retention(RUNTIME)
@Target(FIELD)
public @interface Value {
//默认值
String value() default "";
}
如果注解中只有一个元素且元素名字为 value,那么在使用这个注解的时候,元素的名字和等号都可以省略
@Documented
指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值
@Retention()
- 指明修饰的注解的生存周期,即会保留到哪个阶段
- SOURCE:源码级别保留,编译后即丢弃。
- CLASS:编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
- RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用
@Target({ FIELD, LOCAL_VARIABLE })
指明了修饰的这个注解的使用范围
- TYPE:类,接口或者枚举
- FIELD:域,包含枚举常量
- METHOD:方法
- PARAMETER:参数
- CONSTRUCTOR:构造方法
- LOCAL_VARIABLE:局部变量
- ANNOTATION_TYPE:注解类型
- PACKAGE:包
从缓存中获取单例bean
private Object getSingleton(String beanName){
//若一级缓存有bean,直接返回
Object bean = singletonObjects.get(beanName);
if (bean!=null){
return bean;
}
//如果一级缓存不存在bean,且bean在创建中,则从二级缓存中拿出半成品bean返回,否则从三级缓存拿出放入二级缓存中
if (singletonsCurrennlyInCreation.contains(beanName)){
bean = earlySingletonObjects.get(beanName);
if (bean == null){
ObjectFactory factory = singletonFactories.get(beanName);
if (factory != null){
bean = factory.getObject();
earlySingletonObjects.put(beanName, bean);
singletonFactories.remove(beanName);
}
}
}
return bean;
}