目录
参考文章链接: https://blog.csdn.net/heyl163_/article/details/132515809
IOC容器
Component注解:标记是否要创建bean,传入bean的名称
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
String value() default "";
}
ComponentScan注解:这个是spring启动类上要扫描的路径
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentScan {
String value();
}
创建SpringConfig类,添加注解@ComponentScan指定扫描包
@ComponentScan("org.example")
public class SpringConfig {
}
使用@Component标记需要IOC容器管理的对象
@Component("userMapper")
public class UserMapper {
}
在scan配置类springConfig上的注解@ComponentScan(“org.example”)时,遇到类有标记注解Component就会添加到IOC容器中管理
// 扫描组件 ComponentScan指定的包和Component标记的类
scan(configClass);
//先放入Map中
if (loadClass.isAnnotationPresent(Component.class)) {
// 获取@Component注解上配置的组件名
Component component = loadClass.getAnnotation(Component.class);
beanName = component.value();
if ("".equals(beanName)) {
beanName = getBeanName(loadClass);
}
// 是否懒加载
boolean lazy = false;
// bean的作用域
String scope = "singleton";
// 类上使用了@Scope注解
if (loadClass.isAnnotationPresent(Scope.class)) {
// 获取@Scope注解
Scope annotation = loadClass.getAnnotation(Scope.class);
// 单例
if (isSingleton(annotation.value())) {
lazy = loadClass.isAnnotationPresent(Lazy.class);
} else {
// 非单例
scope = annotation.value();
}
} else {
// 类上没有使用@Scope注解,默认是单例的
lazy = loadClass.isAnnotationPresent(Lazy.class);
}
// 保存bean的定义
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setType(loadClass);
beanDefinition.setLazy(lazy);
beanDefinition.setScope(scope);
// BeanPostProcessor接口的实现类保存到list
if (BeanPostProcessor.class.isAssignableFrom(loadClass)) {
list.add((BeanPostProcessor) createBean(beanDefinition));
} else {
beanDefinitionMap.put(beanName, beanDefinition);
}
beanDefinitionMap.put(beanName, beanDefinition);
//之后遍历创建
// 把组件中非懒加载的单例bean保存到单例池
for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
BeanDefinition beanDefinition = entry.getValue();
if(isSingleton(beanDefinition.getScope()) && !beanDefinition.isLazy()) {
Object bean = createBean(beanDefinition);
String beanName = entry.getKey();
singletonObjects.put(beanName, bean);
}
}
依赖反转/注入
依赖注入,在创建bean对象得时候,看bean的字段是否有Autowired.class注解
if (field.isAnnotationPresent(Autowired.class)) {
有的话就拿字段名字从IOC容器中获取bean,然后再注入
Object autowiredBean = getBean(field.getName());
// 没有找到对应名称的bean,尝试通过bean类型查找,bean的类型就是该字段的类型
if (autowiredBean == null) {
// 获取字段类型
Class<?> type = field.getType();
autowiredBean = getBean((Class<T>) type);
}
// 并设置到@Autowired注入的属性中
field.setAccessible(true);
field.set(bean, autowiredBean);
}
下面是创建bean的代码:
private Object createBean(BeanDefinition beanDefinition) {
Object bean = null;
Class beanType = beanDefinition.getType();
// 获取所有构造方法
Constructor[] constructors = beanType.getConstructors();
try {
/*
* 推断构造方法
* 1、没有提供构造方法:调用默认的无参构造
* 2、提供了构造方法:
* - 构造方法个数为1
* - 构造方法参数个数为0:无参构造
* - 构造方法参数个数不为0:传入多个为空的参数
* - 构造方法个数 > 1:
* - 提供了无参构造方法:调用无参构造方法实例化
* - 没有提供无参构造方法:推断失败,抛出异常
*/
if (isEmpty(constructors)) { // 注意:这个分支永远不会执行,可以删除,但是为了方便理解代码,在此保留
// 无参构造方法
Constructor constructor = beanType.getConstructor();
bean = constructor.newInstance();
} else if (constructors.length == 1) {
Constructor constructor = constructors[0];
// 得到构造方法参数个数
int parameterCount = constructor.getParameterCount();
if (parameterCount == 0) {
// 无参构造方法
bean = constructor.newInstance();
} else {
// 多个参数的构造方法
Object[] array = new Object[parameterCount];
bean = constructor.newInstance(array);
}
} else {
boolean success = false;
for (Constructor constructor : constructors) {
if (constructor.getParameterCount() == 0) {
bean = constructor.newInstance();
success = true;
break;
}
}
if (!success) {
throw new IllegalStateException("No default constructor found.");
}
}
/*
* 处理字段注入
* 先AutowiredByName后AutowiredByType
*/
// 获取bean的所有自定义属性
Field[] fields = beanType.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Autowired.class)) {
// 获取bean
// 通过bean名称获取bean
Object autowiredBean = getBean(field.getName());
// 没有找到对应名称的bean,尝试通过bean类型查找,bean的类型就是该字段的类型
if (autowiredBean == null) {
// 获取字段类型
Class<?> type = field.getType();
autowiredBean = getBean((Class<T>) type);
}
// 并设置到@Autowired注入的属性中
field.setAccessible(true);
field.set(bean, autowiredBean);
}
}
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
return bean;
}
AnnotationConfigApplicationContext spring容器启动类(相当于spring容器)完整简单理解代码
package org.example.spring;
import org.example.spring.annotation.*;
import org.example.spring.exception.NoSuchBeanException;
import org.example.spring.exception.TooMuchBeanException;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author heyunlin
* @version 1.0
*/
public class AnnotationConfigApplicationContext<T> implements ApplicationContext<T> {
private final Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
/**
* 单例对象池
*/
private final Map<String, Object> singletonObjects = new HashMap<>();
/**
* 创建Spring容器时指定的配置类
*/
public final Class<T> configClass;
public AnnotationConfigApplicationContext(Class<T> configClass) throws ClassNotFoundException {
this.configClass = configClass;
// 扫描组件
scan(configClass);
// 把组件中非懒加载的单例bean保存到单例池
for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
BeanDefinition beanDefinition = entry.getValue();
if(isSingleton(beanDefinition.getScope()) && !beanDefinition.isLazy()) {
Object bean = createBean(beanDefinition);
String beanName = entry.getKey();
singletonObjects.put(beanName, bean);
}
}
}
/**
* 扫描组件
* @param clazz 配置类的类对象
* @throws ClassNotFoundException 类找不到
*/
private void scan(Class<T> clazz) throws ClassNotFoundException {
// 如果类上使用了@ComponentScan注解
if (clazz.isAnnotationPresent(ComponentScan.class)) {
ComponentScan componentScan = clazz.getAnnotation(ComponentScan.class);
String value = componentScan.value();
if (!"".equals(value)) {
String path = value;
path = path.replace(".", "/");
URL resource = clazz.getClassLoader().getResource(path);
File file = new File(resource.getFile());
loopFor(file);
}
}
}
/**
* 递归遍历指定文件/文件夹
* @param file 文件/文件夹
* @throws ClassNotFoundException 类找不到
*/
private void loopFor(File file) throws ClassNotFoundException {
if (file.isDirectory()) {
for (File listFile : file.listFiles()) {
if (listFile.isDirectory()) {
loopFor(listFile);
continue;
}
toBeanDefinitionMap(listFile);
}
} else if (file.isFile()) {
toBeanDefinitionMap(file);
}
}
List<BeanPostProcessor> list = new ArrayList<>();
/**
* 解析bean,并保存到Map<String, BeanDefinition>
* @param file 解析的class文件
* @throws ClassNotFoundException 类找不到
*/
private void toBeanDefinitionMap(File file) throws ClassNotFoundException {
// 获取类的绝对路径
String absolutePath = file.getAbsolutePath();
// 处理得到类的全限定名
absolutePath = absolutePath.substring(absolutePath.indexOf("org"), absolutePath.indexOf(".class"));
absolutePath = absolutePath.replace("\\", ".");
// 通过类加载器加载
Class<?> loadClass = configClass.getClassLoader().loadClass(absolutePath);
String beanName;
if (loadClass.isAnnotationPresent(Component.class)) {
// 获取@Component注解上配置的组件名
Component component = loadClass.getAnnotation(Component.class);
beanName = component.value();
if ("".equals(beanName)) {
beanName = getBeanName(loadClass);
}
// 是否懒加载
boolean lazy = false;
// bean的作用域
String scope = "singleton";
// 类上使用了@Scope注解
if (loadClass.isAnnotationPresent(Scope.class)) {
// 获取@Scope注解
Scope annotation = loadClass.getAnnotation(Scope.class);
// 单例
if (isSingleton(annotation.value())) {
lazy = loadClass.isAnnotationPresent(Lazy.class);
} else {
// 非单例
scope = annotation.value();
}
} else {
// 类上没有使用@Scope注解,默认是单例的
lazy = loadClass.isAnnotationPresent(Lazy.class);
}
// 保存bean的定义
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setType(loadClass);
beanDefinition.setLazy(lazy);
beanDefinition.setScope(scope);
// BeanPostProcessor接口的实现类保存到list
if (BeanPostProcessor.class.isAssignableFrom(loadClass)) {
list.add((BeanPostProcessor) createBean(beanDefinition));
} else {
beanDefinitionMap.put(beanName, beanDefinition);
}
beanDefinitionMap.put(beanName, beanDefinition);
} else if (loadClass.isAnnotationPresent(Configuration.class)) {
Method[] methods = loadClass.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Bean.class)) {
Bean annotation = method.getAnnotation(Bean.class);
beanName = annotation.value();
// 是否懒加载
boolean lazy = method.isAnnotationPresent(Lazy.class);
// 作用域
String scope = "singleton";
if ("".equals(beanName)) {
beanName = method.getName();
}
// 保存bean的定义
BeanDefinition beanDefinition = new BeanDefinition();
// 方法的返回值类型就是bean的类型
beanDefinition.setType(method.getReturnType()); // 方法的返回值类型就是bean的类型
beanDefinition.setLazy(lazy);
beanDefinition.setScope(scope);
// BeanPostProcessor接口的实现类保存到list
if (BeanPostProcessor.class.isAssignableFrom(loadClass)) {
list.add((BeanPostProcessor) createBean(beanDefinition));
} else {
beanDefinitionMap.put(beanName, beanDefinition);
}
}
}
}
}
/**
* 根据类对象获取beanName
* @param clazz bean的Class对象
* @return String bean名称
*/
private String getBeanName(Class<?> clazz) {
String beanName = clazz.getSimpleName();
// 判断是否以双大写字母开头
String className = beanName.replaceAll("([A-Z])([A-Z])", "$1_$2");
// 正常的大驼峰命名:bean名称为类名首字母大写
if (className.indexOf("_") != 1) {
beanName = beanName.substring(0, 1).toLowerCase().concat(beanName.substring(1));
} else { // 否则,bean名称为类名
beanName = beanName;
}
return beanName;
}
/**
* 判断作用域是否单例
* @param scope bean的作用域
* @return boolean 如果是单例,返回true,否则返回false
*/
private boolean isSingleton(String scope) {
return "singleton".equals(scope);
}
/**
* 创建bean对象
* @param beanDefinition bean的定义
* @return Object 创建好的bean对象
*/
private Object createBean(BeanDefinition beanDefinition) {
Object bean = null;
Class beanType = beanDefinition.getType();
// 获取所有构造方法
Constructor[] constructors = beanType.getConstructors();
try {
/*
* 推断构造方法
* 1、没有提供构造方法:调用默认的无参构造
* 2、提供了构造方法:
* - 构造方法个数为1
* - 构造方法参数个数为0:无参构造
* - 构造方法参数个数不为0:传入多个为空的参数
* - 构造方法个数 > 1:
* - 提供了无参构造方法:调用无参构造方法实例化
* - 没有提供无参构造方法:推断失败,抛出异常
*/
if (isEmpty(constructors)) { // 注意:这个分支永远不会执行,可以删除,但是为了方便理解代码,在此保留
// 无参构造方法
Constructor constructor = beanType.getConstructor();
bean = constructor.newInstance();
} else if (constructors.length == 1) {
Constructor constructor = constructors[0];
// 得到构造方法参数个数
int parameterCount = constructor.getParameterCount();
if (parameterCount == 0) {
// 无参构造方法
bean = constructor.newInstance();
} else {
// 多个参数的构造方法
Object[] array = new Object[parameterCount];
bean = constructor.newInstance(array);
}
} else {
boolean success = false;
for (Constructor constructor : constructors) {
if (constructor.getParameterCount() == 0) {
bean = constructor.newInstance();
success = true;
break;
}
}
if (!success) {
throw new IllegalStateException("No default constructor found.");
}
}
/*
* 处理字段注入
* 先AutowiredByName后AutowiredByType
*/
// 获取bean的所有自定义属性
Field[] fields = beanType.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Autowired.class)) {
// 获取bean
// 通过bean名称获取bean
Object autowiredBean = getBean(field.getName());
// 没有找到对应名称的bean,尝试通过bean类型查找,bean的类型就是该字段的类型
if (autowiredBean == null) {
// 获取字段类型
Class<?> type = field.getType();
autowiredBean = getBean((Class<T>) type);
}
// 并设置到@Autowired注入的属性中
field.setAccessible(true);
field.set(bean, autowiredBean);
}
}
// 调用InitializingBean的afterPropertiesSet()方法
// if (bean instanceof InitializingBean) {
Method afterPropertiesSet = beanType.getDeclaredMethod("afterPropertiesSet");
afterPropertiesSet.invoke(bean);
// ((InitializingBean) bean).afterPropertiesSet();
// }
/*
* 初始化前
*/
String beanName = getBeanName(beanDefinition.getType());
if (!list.isEmpty()) {
for (BeanPostProcessor beanPostProcessor : list) {
bean = beanPostProcessor.postProcessBeforeInitialization(bean, beanName);
}
}
// 调用InitializingBean的afterPropertiesSet()方法
if (bean instanceof InitializingBean) {
((InitializingBean) bean).afterPropertiesSet();
}
/*
* 初始化后
*/
if (list.size() > 0) {
for (BeanPostProcessor beanPostProcessor : list) {
bean = beanPostProcessor.postProcessAfterInitialization(bean, beanName);
}
}
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
e.printStackTrace();
}
return bean;
}
private boolean isEmpty(Object[] array) {
return array.length == 0;
}
@Override
public Object getBean(String beanName) {
if (!beanDefinitionMap.containsKey(beanName)) {
return null;
}
return getBean(beanName, beanDefinitionMap.get(beanName));
}
@Override
public T getBean(Class<T> type) {
if (type == null) {
throw new IllegalStateException("bean类型不能为空!");
}
// 保存指定类型的bean的个数
AtomicInteger count = new AtomicInteger();
// 保存同一类型的bean
Map<String, BeanDefinition> objectMap = new HashMap<>();
for (Map.Entry<String, BeanDefinition> entry : beanDefinitionMap.entrySet()) {
BeanDefinition beanDefinition = entry.getValue();
Class beanType = beanDefinition.getType();
String beanName = entry.getKey();
if (beanType.equals(type)) {
count.addAndGet(1);
objectMap.put(beanName, beanDefinition);
}
}
if (count.get() == 0) {
throw new NoSuchBeanException();
} else if (count.get() > 1) {
throw new TooMuchBeanException();
} else {
return (T) getBean((String) objectMap.keySet().toArray()[0], (BeanDefinition) objectMap.values().toArray()[0]);
}
}
@Override
public T getBean(String beanName, Class<T> type) {
if (type == null) {
throw new IllegalStateException("bean类型不能为空!");
}
if (beanDefinitionMap.containsKey(beanName)) {
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if (type.equals(beanDefinition.getType())) {
return (T) getBean(beanName, beanDefinition);
}
}
throw new NoSuchBeanException();
}
/**
* 统一获取bean的方法
* @param beanName bean名称
* @param beanDefinition BeanDefinition
* @return Object 符合条件的bean对象
*/
private Object getBean(String beanName, BeanDefinition beanDefinition) {
String scope = beanDefinition.getScope();
// bean的作用域是单例
if (isSingleton(scope)) {
Object object = singletonObjects.get(beanName);
// 懒加载的单例bean
if (object == null) {
Object bean = createBean(beanDefinition);
singletonObjects.put(beanName, bean);
}
return singletonObjects.get(beanName);
}
return createBean(beanDefinition);
}
}
标签:容器,String,构造方法,反转,beanName,bean,IOC,class,beanDefinition
From: https://blog.csdn.net/LSP20020926/article/details/142446207