IoC
IocЭто упрощенная версия основных функций Spring ioc, которую легко изучить и понять принцип.
творческая цель
Spring использую давно, причем очень часто, на самом деле я так и не успокоился и не изучил исходный код.
Однако есть проблема с исходным кодом spring, то есть он слишком абстрактный, что приводит к увеличению стоимости обучения.
Поэтому этот проект постепенно углубляется и реализует только основные функции спринга, чтобы и себе, и другим было удобно изучать основные принципы спринга.
сердцевина весны
Ядро Spring — это spring-beans, и все, что стоит за spring-boot и spring-cloud, построено на этом фундаменте.
Когда кто-то спросит вас о Spring, я надеюсь, вы сможете рассказать о своем собственном более глубоком понимании Spring ioc, а не просто об этом в Интернете.
Что такое МОК
Инверсия управления (сокращенно IoC) — это принцип проектирования в объектно-ориентированном программировании, который можно использовать для уменьшения связи между компьютерными кодами.
Наиболее распространенный способ называется внедрение зависимостей (DI).
Посредством инверсии управления при создании объекта внешний объект, управляющий всеми объектами в системе, передает ему ссылку на объект, от которого он зависит.
Можно также сказать, что зависимости внедряются в объекты.
Зачем нужны МОК
IoC — это метод развязки.
Мы знаем, что Java — объектно-ориентированный язык, в Java все является объектом, и наша программа состоит из нескольких объектов.
Когда наш проект будет становиться все больше и больше, и будет все больше и больше сотрудничающих разработчиков, у нас будет все больше и больше классов, а ссылки между классами будут расти в геометрической прогрессии.
Такой проект просто катастрофа, если ввести Ioc framework.
Платформа должна поддерживать жизненный цикл классов и ссылок между классами.
Наша система будет выглядеть так:
На этот раз мы обнаружили, что связь между нашими классами поддерживается инфраструктурой IoC, а классы внедряются в требуемые классы.
То есть пользователь класса отвечает только за использование, а не за обслуживание.
Доверение профессиональных вещей профессиональным фреймворкам значительно снижает сложность разработки.
быстрый старт
импорт maven
<dependency>
<groupId>com.github.houbb</groupId>
<artifactId>ioc</artifactId>
<version>0.1.11</version>
</dependency>
подготовка к тесту
Весь тестовый код смотрите в тестовом модуле.
- Apple.java
public class Apple {
public void color() {
System.out.println("Apple color: red. ");
}
}
- apple.json
Подобно конфигурации xml, мы временно используем json для проверки конфигурации.
[
{"name":"apple","className":"com.github.houbb.ioc.test.service.Apple"}
]
выполнить тест
- контрольная работа
BeanFactory beanFactory = new JsonApplicationContext("apple.json");
Apple apple = (Apple) beanFactory.getBean("apple");
apple.color();
- бревно
Apple color: red.
Базовый процесс реализации Spring
инструкция
Все в spring-beans вращается вокруг бобов.
BeanFactory отвечает за управление жизненным циклом bean-компонентов.В этом разделе показан простой процесс реализации первого раздела.
Основной процесс Spring
Spring IoC в основном состоит из следующих шагов.
-
Инициализируйте контейнер IoC.
-
Прочтите файл конфигурации.
-
Преобразуйте файл конфигурации в структуру данных, идентифицируемую контейнером (эта структура данных называется BeanDefinition в Spring).
-
Используйте структуру данных для поочередного создания экземпляров соответствующих объектов.
-
внедрять зависимости между объектами
Абстракция BeanDefinition
BeanDefinition — это абстракция свойств java bean от spring.После этого уровня абстракции файл конфигурации может быть любым из xml/json/properties/yaml и даже включать пакеты сканирования аннотаций.
Это обеспечивает большую гибкость при расширении пружины.
Учитывая простоту реализации, этот фреймворк изначально реализует только json и сканирование пакетов на основе аннотаций.
Если на более позднем этапе есть время, вы можете рассмотреть возможность добавления реализации xml.На самом деле, это больше рабочей нагрузки по разбору xml, а основной процесс уже полностью реализован.
Реализовать фрагменты исходного кода
BeanDefinition связанные
Содержит базовую информационную абстракцию для java bean-компонентов.
- BeanDefinition.java
Его реализация по умолчаниюDefaultBeanDefinition.java
, который является самым простым java POJO, реализующим интерфейс
видетьDefaultBeanDefinition
/**
* 对象定义属性
* @author binbin.hou
* @since 0.0.1
*/
public interface BeanDefinition {
/**
* 名称
* @return 名称
* @since 0.0.1
*/
String getName();
/**
* 设置名称
* @param name 名称
* @since 0.0.1
*/
void setName(final String name);
/**
* 类名称
* @return 类名称
*/
String getClassName();
/**
* 设置类名称
* @param className 类名称
* @since 0.0.1
*/
void setClassName(final String className);
}
Управление ядром BeanFactory, связанное с
- BeanFactory.java
/**
* bean 工厂接口
* @author binbin.hou
* @since 0.0.1
*/
public interface BeanFactory {
/**
* 根据名称获取对应的实例信息
* @param beanName bean 名称
* @return 对象信息
* @since 0.0.1
*/
Object getBean(final String beanName);
/**
* 获取指定类型的实现
* @param beanName 属性名称
* @param tClass 类型
* @param <T> 泛型
* @return 结果
* @since 0.0.1
*/
<T> T getBean(final String beanName, final Class<T> tClass);
}
- DefaultBeanFactory.java
Для самой базовой реализации интерфейса исходный код выглядит следующим образом:
/**
* bean 工厂接口
* @author binbin.hou
* @since 0.0.1
*/
public class DefaultBeanFactory implements BeanFactory {
/**
* 对象信息 map
* @since 0.0.1
*/
private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
/**
* 对象 map
* @since 0.0.1
*/
private Map<String, Object> beanMap = new ConcurrentHashMap<>();
/**
* 注册对象定义信息
* @since 0.0.1
*/
protected void registerBeanDefinition(final String beanName, final BeanDefinition beanDefinition) {
// 这里可以添加监听器
this.beanDefinitionMap.put(beanName, beanDefinition);
}
@Override
public Object getBean(String beanName) {
Object bean = beanMap.get(beanName);
if(ObjectUtil.isNotNull(bean)) {
// 这里直接返回的是单例,如果用户指定为多例,则每次都需要新建。
return bean;
}
// 获取对应配置信息
BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
if(ObjectUtil.isNull(beanDefinition)) {
throw new IocRuntimeException(beanName + " not exists in bean define.");
}
// 直接根据
Object newBean = createBean(beanDefinition);
// 这里可以添加对应的监听器
beanMap.put(beanName, newBean);
return newBean;
}
/**
* 根据对象定义信息创建对象
* @param beanDefinition 对象定义信息
* @return 创建的对象信息
* @since 0.0.1
*/
private Object createBean(final BeanDefinition beanDefinition) {
String className = beanDefinition.getClassName();
Class clazz = ClassUtils.getClass(className);
return ClassUtils.newInstance(clazz);
}
@Override
@SuppressWarnings("unchecked")
public <T> T getBean(String beanName, Class<T> tClass) {
Object object = getBean(beanName);
return (T)object;
}
}
Среди них ClassUtils — класс инструментов отражения на основе классов.ClassUtils.java
JsonApplicationContext
Базовая реализация основана на конфигурационном файле json, см. пример кода в начале использования.
- JsonApplicationContext.java
/**
* JSON 应用上下文
* @author binbin.hou
* @since 0.0.1
*/
public class JsonApplicationContext extends DefaultBeanFactory {
/**
* 文件名称
* @since 0.0.1
*/
private final String fileName;
public JsonApplicationContext(String fileName) {
this.fileName = fileName;
// 初始化配置
this.init();
}
/**
* 初始化配置相关信息
*
* <pre>
* new TypeReference<List<BeanDefinition>>(){}
* </pre>
*
* 读取文件:https://blog.csdn.net/feeltouch/article/details/83796764
* @since 0.0.1
*/
private void init() {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
final String jsonConfig = FileUtil.getFileContent(is);
List<DefaultBeanDefinition> beanDefinitions = JsonBs.deserializeArray(jsonConfig, DefaultBeanDefinition.class);
if(CollectionUtil.isNotEmpty(beanDefinitions)) {
for (BeanDefinition beanDefinition : beanDefinitions) {
super.registerBeanDefinition(beanDefinition.getName(), beanDefinition);
}
}
}
}
резюме
На данный момент базовый Spring ioc в основном реализован.
Если вы хотите продолжить обучение, вы можете обратиться к следующим ветвям кода соответственно.
описание ветки
v0.0.1-BeanFactory базовая реализация
v0.0.2-ListBeanFactory базовая реализация
v0.0.3 - Одиночки и отложенная загрузка
v0.0.4 - методы инициализации и уничтожения
v0.0.5 - Дополнения RespCode и оптимизация кода
v0.0.6 - Конструктор и factoryMethod для создания новых объектов
v0.0.7-свойство настройки свойства
v0.0.8-Aware Listener и PostProcessor
v0.0.9 - Наследование родительского свойства
v0.1.0 - Циклическое обнаружение зависимостей
v0.1.1-@Configuration-конфигурация кода Java
v0.1.2 - определение объекта @Bean-java
v0.1.3-@Lazy-@Scope-конфигурация свойства объекта Java
v0.1.4 - Импорт конфигурации @Import
v0.1.5 - Построение параметров @Bean и @Description
v0.1.6 - поддержка автоматически подключаемых аннотаций @Autowired
v0.1.7 - @Primary указывает аннотацию приоритета
v0.1.8 - Поддержка условной аннотации @Conditional
v0.1.9 - Реализация среды и @Profile
v0.1.10 - Связанный профиль свойства и реализация @Value/@PropertyResource
v0.1.11 - Поддержка сканирования пакетов @ComponentScan