IoC да Инверсия управления из аббревиатуры,Переводится как «инверсия управления».,Это не технология,ида Что-то вродеДизайнерское мышление,важное правило изориентированного объектного программирования,Это может помочь нам в разработке слабосвязанных и более эффективных программ.
Spring проходить IoC-контейнеруправлятьвсе Java-объекты, инициализация и инициализация,Контролируйте зависимости между объектом и объектом。Мы будем IoC управляемый контейнером Java объект называется Spring Bean,Он использует ключевое слово new Создано Java. В объектах нет никакой разницы.
IoC-контейнерда Spring Один из наиболее важных основных компонентов структуры, он проходит через Spring Весь процесс от рождения до роста.
DI (Dependency Injection): внедрение зависимостей, реализующее идею инверсии управления.
Внедрение зависимостей:
Существует два распространенных метода реализации внедрения зависимостей:
Итак, в заключениеда:IOC Просто своего рода инверсия управляющей мысли, и DI да — это конкретная реализация IoCиз.
Управление компонентами говорит изда: создание объекта Beanобъекта и атрибут назначения объекта Bean (или связь между объектом Bean из обслуживания).
Spring из IoC-контейнер Сразуда Идея IoC реализована в практичном продукте. Управление компонентом в IoCконтейнере еще называют бобы. Создание bean Раньше вам сначала нужно было создать IoC контейнер. Весна IoC предоставил контейнериз Два способа добиться этого:
①BeanFactory
Да IoC-контейнериз Базовая реализация, да Spring Интерфейс используется внутри. Для Spring Сам по себе он недоступен разработчикам.
②ApplicationContext
BeanFactory из субинтерфейса, предоставляющего более продвинутые функции. Для Spring из пользователей, используйте его практически во всех случаях ApplicationContext иNodabottomиз BeanFactory。
③Класс реализации ApplicationContextизMain
Введите имя | Введение |
---|---|
ClassPathXmlApplicationContext | Далее читает путь к классам из XML Формат создания файла конфигурации IOC объект-контейнер |
FileSystemXmlApplicationContext | передать чтение пути к файловой системе XML Формат создания файла конфигурации IOC объект-контейнер |
ConfigurableApplicationContext | ApplicationContext из субинтерфейса, включая некоторые методы расширения refresh() и close() ,позволять ApplicationContext Он имеет возможность запускать, завершать работу и обновлять контекст. |
WebApplicationContext | специально для Web Подготовка заявки на основе Web создание среды IOC объект-контейнер и объект импорта ServletContext в домене. |
①Сборка модулей
Способ строительства: весенний.
②Введение файлов конфигурации
Представляем файлы конфигурации модуля Spring-First: beans.xml, log4j2.xml.
③Добавить зависимости
<dependencies>
<!--spring contextполагаться-->
<!--когда ты представляешьSpring Contextполагатьсяпосле,Указывает на то, что это будетSpringиз Базаполагатьсяпредставил-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.11</version>
</dependency>
<!--junit5тест-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
</dependency>
<!--log4j2изполагаться-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
④Введение класса Java
Представляем класс Java-сущности модуля Spring-First
потому что id Атрибут указан bean из уникального идентификатора, поэтому согласно bean Теги id Свойства могут точно получить объект-компонент. Передний Мы рождаемся Для начала используйте этот метод: из.
когда на основетипКогда получаешь боб,ТребоватьIOCконтейнеруказано втипизЕсть и может быть только один боб
Если в контейнере IOC настроено всего два:
Затем мы получаем Bean в зависимости от типа.
Будет выброшено исключение.
Если класс компонента реализует интерфейс, можно ли получить компонент на основе типа интерфейса?
Да, предполагается, что дабеан единственный
package com.jie.ioc.service;
/**
* @Auther: Administrator
* @Date: 2023/08/30/15:38
* @Description:
*/
public interface HelloWorldService {
void run();
}
package com.jie.ioc.service.impl;
import com.jie.ioc.HelloWorldTest;
import com.jie.ioc.service.HelloWorldService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author JIE
* @version 1.0
* @description: TODO
* @date 2023/8/30 15:39
*/
public class HelloWorldServiceImpl implements HelloWorldService {
private final Logger logger = LoggerFactory.getLogger(HelloWorldTest.class);
@Override
public void run() {
logger.info("Вызов метода");
}
}
Результаты испытаний:
Если интерфейс имеет несколько классов реализации, и эти классы реализации настроены с помощью bean-компонентов, можно ли получить bean-компоненты на основе типа интерфейса?
Нет, потому что бин не уникален
package com.jie.ioc.service.impl;
import com.jie.ioc.HelloWorldTest;
import com.jie.ioc.service.HelloWorldService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author JIE
* @version 1.0
* @description: Второй класс реализации
* @date 2023/8/30 15:39
*/
public class HelloWorldServiceImpl2 implements HelloWorldService {
private final Logger logger = LoggerFactory.getLogger(HelloWorldTest.class);
@Override
public void run() {
logger.info("Вызов метода");
}
}
Результаты испытаний:
в заключение
По типу Когда получаешь боб, если исходить из того, что компонент удовлетворяет уникальности, на самом деле можно увидеть только да: 『объект instanceof обозначениеизтип』из Возврат результатов,Пока возвращается значение isdatrue, его можно рассматривать как совпадение итипа.,можно получить.
в Яве,Оператор экземпляра используется для определения того, является ли предыдущий объект следующим из класса.,Или его подклассы или экземпляры класса реализации. если да возвращает true,В противном случае верните false. Другими словами, да сказал: при использовании ключевого слова instanceof для вынесения суждения, instanceof Левая и правая операции оператора из должны иметь отношения наследования или реализации.
package com.jie.ioc.model;
public class Student {
private Integer id;
private String name;
private Integer age;
private String sex;
public Student() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
<bean id="studentOne" class="com.jie.ioc.model.Student">
<!-- Тег свойства: применить класс компонента. Метод issetXxx() устанавливает свойства для объекта компонента. -->
<!-- Атрибут name: укажите имя атрибута (это имя атрибута определяется методами getXxx() и setXxx() и не имеет ничего общего с переменными-членами) -->
<!-- атрибут value: указывает значение атрибута -->
<property name="id" value="1001"/>
<property name="name" value="Чжан Сан"/>
<property name="age" value="23"/>
<property name="sex" value="мужской"/>
</bean>
@Test
public void testDIBySet(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
Student studentOne = ac.getBean("studentOne", Student.class);
System.out.println(studentOne);
}
public Student(Integer id, String name, Integer age, String sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
spring-di.xml
<bean id="studentTwo" class="com.jie.ioc.model.Student">
<constructor-arg value="1002"/>
<constructor-arg value="Джон Доу"/>
<constructor-arg value="33"/>
<constructor-arg value="женский"/>
</bean>
Уведомление: Тегstructor-arg также имеет два атрибута, которые дополнительно описывают параметры конструктора:
@Test
public void testDIByConstructor(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
Student studentOne = ac.getBean("studentTwo", Student.class);
System.out.println(studentOne);
}
Что в буквальном смысле? int a = 10; Объявить переменную a,инициализирован до 10,В настоящее время a не представляет букву a.,идакак переменная по имени。когда мы цитируемaизкогда,Фактически мы получаем значение да10. Если ада в кавычках из: ‘a’, то это теперь не переменная, а представляет собой саму букву а, которая является литералом да. Следовательно, литерал не расширяет значение, мы видим данные только сами по себе.
<!-- При использовании атрибута value для присвоения значения атрибуту bean-компонента Spring будет рассматривать атрибут value как литерал. -->
<property name="name" value="Чжан Сан"/>
<property name="name">
<null />
</property>
Уведомление:
<property name="name" value="null"></property>
Вышеупомянутый метод записи представляет собой строку null, присвоенную имени.
<!-- меньше, чем войтиXMLиспользуется для определения в документе Тегиначинать,нельзя использовать случайно -->
<!-- Решение 1. Вместо этого используйте сущности XML -->
<property name="expression" value="a < b"/>
<property name="expression">
<!-- Решение второе: используйте раздел CDATA -->
<!-- изC в CDATA представляет собой символ, да текст, обозначение символа, CDATA представляет собой текстовые данные -->
<!-- Когда анализатор XML видит раздел CDATA, он знает, что это обычный текст, и не будет анализировать его как тег или атрибут XML. -->
<!-- Таким образом, вы можете писать любые символы в разделе CDATA. -->
<value><![CDATA[a < b]]></value>
</property>
package com.jie.ioc.model;
public class Clazz {
private Integer clazzId;
private String clazzName;
public Integer getClazzId() {
return clazzId;
}
public void setClazzId(Integer clazzId) {
this.clazzId = clazzId;
}
public String getClazzName() {
return clazzName;
}
public void setClazzName(String clazzName) {
this.clazzName = clazzName;
}
@Override
public String toString() {
return "Clazz{" +
"clazzId=" + clazzId +
", clazzName='" + clazzName + '\'' +
'}';
}
public Clazz() {
}
public Clazz(Integer clazzId, String clazzName) {
this.clazzId = clazzId;
this.clazzName = clazzName;
}
}
Добавьте следующий код в класс Student:
private Clazz clazz;
public Clazz getClazz() {
return clazz;
}
public void setClazz(Clazz clazz) {
this.clazz = clazz;
}
Настройте Clazzтипизбин:
<bean id="clazzOne" class="com.jie.ioc.model.Clazz">
<property name="clazzId" value="1111"/>
<property name="clazzName" value="Богатство денежного класса"/>
</bean>
Присвойте значение атрибуту изclazz в Student:
<bean id="studentOne" class="com.jie.ioc.model.Student">
<!-- Тег свойства: применить класс компонента. Метод issetXxx() устанавливает свойства для объекта компонента. -->
<!-- Атрибут name: укажите имя атрибута (это имя атрибута определяется методами getXxx() и setXxx() и не имеет ничего общего с переменными-членами) -->
<!-- атрибут value: указывает значение атрибута -->
<property name="id" value="1001"/>
<property name="name" value="null"/>
<property name="age" value="23"/>
<property name="sex" value="мужской"/>
<!-- Атрибут Ref: ссылается на определенный идентификатор компонента в IOCконтейнере и присваивает атрибуту соответствующий компонент. -->
<property name="clazz" ref="clazzOne"/>
</bean>
Результаты испытаний:
Не забудьте восстановить метод toString.
Демонстрация ошибки:
Если атрибут ref ошибочно записан как атрибут value, будет выдано исключение: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘studentOne’ defined in class path resource [bean.xml]: Failed to convert property value of type ‘java.lang.String’ to required type ‘com.jie.ioc.model.Clazz’ for property ‘clazz’; Cannot convert value of type ‘java.lang.String’ to required type ‘com.jie.ioc.model.Clazz’ for property ‘clazz’: no matching editors or conversion strategy found Это означает, что да не может преобразовать тип String в то, что мы хотим, из Clazzтип, иллюстрировать. Когда мы используем атрибут value, Spring рассматривает этот атрибут только как обычный из строки и не считает это да идентификатором bean-компонента, не говоря уже о поиске bean-компонента на основе это для присвоения значения.
<bean id="studentOne" class="com.jie.ioc.model.Student">
<!-- Тег свойства: применить класс компонента. Метод issetXxx() устанавливает свойства для объекта компонента. -->
<!-- Атрибут name: укажите имя атрибута (это имя атрибута определяется методами getXxx() и setXxx() и не имеет ничего общего с переменными-членами) -->
<!-- атрибут value: указывает значение атрибута -->
<property name="id" value="1001"/>
<property name="name" value="null"/>
<property name="age" value="23"/>
<property name="sex" value="мужской"/>
<property name="clazz">
<!-- Объявление bean-компонента внутри bean-компонента является внутренним bean-компонентом. -->
<!-- Внутренние bean-компоненты могут использоваться только для присвоения значений свойствам и не могут быть получены из внешнего источникаIOCконтейнера, поэтому атрибут id можно опустить. -->
<bean class="com.jie.ioc.model.Clazz">
<property name="clazzId" value="2222"/>
<property name="clazzName" value="Класс «Большие надежды»"/>
</bean>
</property>
</bean>
Результаты испытаний:
<bean id="studentOne" class="com.jie.ioc.model.Student">
<!-- Тег свойства: применить класс компонента. Метод issetXxx() устанавливает свойства для объекта компонента. -->
<!-- Атрибут name: укажите имя атрибута (это имя атрибута определяется методами getXxx() и setXxx() и не имеет ничего общего с переменными-членами) -->
<!-- атрибут value: указывает значение атрибута -->
<property name="id" value="1001"/>
<property name="name" value="null"/>
<property name="age" value="23"/>
<property name="sex" value="мужской"/>
<property name="clazz" ref="clazzOne"/>
<property name="clazz.clazzId" value="3333"/>
<property name="clazz.clazzName" value="Самый сильный королевский класс"/>
</bean>
Результаты испытаний:
Добавьте следующий код в класс Student:
private String[] hobbies;
public String[] getHobbies() {
return hobbies;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
<bean id="studentOne" class="com.jie.ioc.model.Student">
<!-- Тег свойства: применить класс компонента. Метод issetXxx() устанавливает свойства для объекта компонента. -->
<!-- Атрибут name: укажите имя атрибута (это имя атрибута определяется методами getXxx() и setXxx() и не имеет ничего общего с переменными-членами) -->
<!-- атрибут value: указывает значение атрибута -->
<property name="id" value="1001"/>
<property name="name" value="null"/>
<property name="age" value="23"/>
<property name="sex" value="мужской"/>
<property name="clazz" ref="clazzOne"/>
<property name="clazz.clazzId" value="3333"/>
<property name="clazz.clazzName" value="Самый сильный королевский класс"/>
<property name="hobbies">
<array>
<value>курить</value>
<value>пить вино</value>
<value>Пермь</value>
</array>
</property>
</bean>
Результаты испытаний:
Не забудьте изменить toString.
Добавьте следующий код в класс Clazz:
private List<Student> students;
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
Настройте bean-компоненты:
<bean id="clazzOne" class="com.jie.ioc.model.Clazz">
<property name="clazzId" value="1111"/>
<property name="clazzName" value="Богатство денежного класса"/>
<property name="students">
<list>
<ref bean="studentTwo"/>
<ref bean="studentOne"/>
</list>
</property>
</bean>
Результаты испытаний:
Если вы присвоите значение атрибуту Set, вам нужно будет только изменить тег izlist на тег set.
Создайте класс учителя Учитель:
package com.atguigu.spring6.bean;
public class Teacher {
private Integer teacherId;
private String teacherName;
public Integer getTeacherId() {
return teacherId;
}
public void setTeacherId(Integer teacherId) {
this.teacherId = teacherId;
}
public String getTeacherName() {
return teacherName;
}
public void setTeacherName(String teacherName) {
this.teacherName = teacherName;
}
public Teacher(Integer teacherId, String teacherName) {
this.teacherId = teacherId;
this.teacherName = teacherName;
}
public Teacher() {
}
@Override
public String toString() {
return "Teacher{" +
"teacherId=" + teacherId +
", teacherName='" + teacherName + '\'' +
'}';
}
}
Добавьте следующий код в класс Student:
private Map<String, Teacher> teacherMap;
public Map<String, Teacher> getTeacherMap() {
return teacherMap;
}
public void setTeacherMap(Map<String, Teacher> teacherMap) {
this.teacherMap = teacherMap;
}
Настройте bean-компоненты:
<bean id="teacherOne" class="com.jie.ioc.model.Teacher">
<property name="teacherId" value="10010"/>
<property name="teacherName" value="Дабао"/>
</bean>
<bean id="teacherTwo" class="com.jie.ioc.model.Teacher">
<property name="teacherId" value="10086"/>
<property name="teacherName" value="Эрбао"/>
</bean>
<bean id="studentOne" class="com.jie.ioc.model.Student">
<!-- Тег свойства: применить класс компонента. Метод issetXxx() устанавливает свойства для объекта компонента. -->
<!-- Атрибут name: укажите имя атрибута (это имя атрибута определяется методами getXxx() и setXxx() и не имеет ничего общего с переменными-членами) -->
<!-- атрибут value: указывает значение атрибута -->
<property name="id" value="1001"/>
<property name="name" value="null"/>
<property name="age" value="23"/>
<property name="sex" value="мужской"/>
<property name="hobbies">
<array>
<value>курить</value>
<value>пить вино</value>
<value>Пермь</value>
</array>
</property>
<property name="teacherMap">
<map>
<entry key="10010" value-ref="teacherOne"/>
<entry key="10086" value-ref="teacherTwo"/>
</map>
</property>
</bean>
Результаты испытаний:
Если мы хотим использовать теги util:list и util:map, мы должны ввести соответствующее пространство имен.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--listсобиратьтипизbean-->
<util:list id="students">
<ref bean="studentOne"/>
<ref bean="studentTwo"/>
</util:list>
<!--mapсобиратьтипизbean-->
<util:map id="teacherMap">
<entry key="10010" value-ref="teacherOne"/>
<entry key="10086" value-ref="teacherTwo"/>
</util:map>
<bean id="studentOne" class="com.jie.ioc.model.Student">
<!-- Тег свойства: применить класс компонента. Метод issetXxx() устанавливает свойства для объекта компонента. -->
<!-- Атрибут name: укажите имя атрибута (это имя атрибута определяется методами getXxx() и setXxx() и не имеет ничего общего с переменными-членами) -->
<!-- атрибут value: указывает значение атрибута -->
<property name="id" value="1001"/>
<property name="name" value="null"/>
<property name="age" value="23"/>
<property name="sex" value="мужской"/>
<property name="hobbies">
<array>
<value>курить</value>
<value>пить вино</value>
<value>Пермь</value>
</array>
</property>
<property name="teacherMap" ref="teacherMap"/>
</bean>
<bean id="clazzOne" class="com.jie.ioc.model.Clazz">
<property name="clazzId" value="1111"/>
<property name="clazzName" value="Богатство денежного класса"/>
<property name="students" ref="students"/>
</bean>
Результаты испытаний:
Во-первых, позвольте мне объяснить, что такое пространство имен или пространство имен.
Внимание всем, в «Эксперимент 7: Присвоение значений свойствам типа коллекции» серединаиз Справочная коллекция Во время демонстрации. мы добавили
эта часть,его название да util, Добавлю сюда еще один.
Например, посмотрите, как я сейчас пишу вилку xmlns.,Внимание всем,Сейчас на этом ярлыке,Имя его атрибута да или да называется xmlns. Если вы сейчас так напишете, то это точно неправильно!
Поскольку у вас не может быть двух свойств с одинаковым именем, мы можем добавить раздел.
Например, добавление буквы P называется пространством имен. Вы можете просто понять, что это делается для того, чтобы избежать конфликтов в определениях атрибутов в тегах. Затем добавьте после него такой адрес и используйте его для завершения процесса внедрения после его завершения.
После завершения давайте проведем быстрый тест, чтобы опробовать этот эффект.
Далее мы научимся вводить файлы внешних свойств.
Позвольте мне сначала поговорить об этом Импортировать файлы внешних свойствизнеобходимость,илиэтоиз Сценарии примененияда Как насчет этого。Внимание всем,Просто дая теперь наделен различными атрибутами,Мы все были записаны почти в одном файле.
Если, скажем, вам ввели только один компонент, это не имеет значения. Но в большинстве случаев у нас не может быть только одного боба.
В это время все обнаружили, что у нас здесь много бобов.,Есть много чего, что стоит ввести. Тогда нам придется внести некоторые изменения,Требуется дополнительное обслуживание,Особенно неудобно, если да не да.
На практике мы обычно делаем это так,Поместите некоторые конкретные и фиксированные значения во внешний файл.,Затем введите внешний файл и внедрите его внутрь.
Это более распространено, чем изменение базы данных. Например, наши данные имеют имя пользователя.,Есть пароль,Есть такая информация, как адрес. Тогда давайте напишем внешний файл,Импортируйте файл,Введите его внутрь,Это облегчает нам выполнение технического обслуживания. Если я хочу изменить базу данных сейчас,Тогда давайте изменим мой внешний файл. иspringиз вставить файл,Тогда нам не нужно его модифицировать,Это основное требование.
Далее займемся реализацией.
<!-- Драйвер MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- источник данных -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.16</version>
</dependency>
jdbc.user=root
jdbc.password=ajie
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.driver=com.mysql.cj.jdbc.Driver
Введение контекстного пространства имен
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
<!-- Импортировать файлы внешних свойств -->
<context:property-placeholder location="classpath:jdbc.properties"/>
Уведомление: Используется context:property-placeholder Прежде чем элемент загрузит функцию файла конфигурации аутсорсинга, его сначала необходимо XML Настройка метки первого уровня Добавить context Связано с ограничениями.
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
@Test
public void testDataSource() throws SQLException {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.jdbc.xml");
DataSource dataSource = ac.getBean(DataSource.class);
DruidDataSource bean = ac.getBean(DruidDataSource.class);
System.out.println(bean.getUrl());
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
существоватьSpringсередина Можетпроходить КонфигурацияbeanТегиscopeатрибуты приходятобозначениеbeanиз Объем,каждыйценитьзначение Присоединяйтесь к таблице ниже:
ценить | значение | Время создавать объектиз |
---|---|---|
синглтон (по умолчанию) | В IOCконтейнере этот bean-объект всегда является единственным экземпляром. | Когда контейнер IOC инициализируется |
prototype | Этот компонент имеет несколько экземпляров в контейнере IOC. | Когда получаешь боб |
Если да имеет несколько других областей в среде WebApplicationContext (но не часто используемых):
ценить | значение |
---|---|
request | Действительно в пределах области запроса |
session | Действительно в пределах сеанса |
package com.jie.ioc.model;
/**
* Класс пользовательской сущности
*
* @author Аджи 2416338031@qq.com
* @version 1.0
* @date 2023/9/3 14:33
*/
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
public User() {
}
public User(Integer id, String username, String password, Integer age) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
'}';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Атрибут области действия: ценитьsingleton (значение по умолчанию), компонент имеет только один экземпляр в IOCконтейнере, Когда контейнер IOC инициализируетсясоздаватьобъект -->
<!-- Атрибут области видимости: ценитьprototype, bean-компонент может иметь несколько экземпляров в IOCконтейнере, создавать объект при getBean() -->
<bean id="user" class="com.jie.ioc.model.User" scope="prototype"/>
</beans>
Да Шаблон с несколькими экземплярами,Создано изда двух разных изобъектов,Давайте попробуем перейти на синглтон.
@Test
public void testBeanScope(){
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-scope.xml");
User user1 = ac.getBean(User.class);
User user2 = ac.getBean(User.class);
System.out.println(user1==user2);
}
Что такое жизненный цикл? Если говорить о жизненном цикле человека,Далее идет процесс от рождения до смерти даот. Если мы теперь поговорим о жизненном цикле Bean,Это означает создание объекта для уничтожения из процесса.,Это называется жизненным циклом.
package com.jie.ioc.model;
/**
* Класс пользовательской сущности
*
* @author Аджи 2416338031@qq.com
* @version 1.0
* @date 2023/9/3 14:33
*/
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
public User() {
System.out.println("Жизненный цикл: 1. Создать объект");
}
public User(Integer id, String username, String password, Integer age) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
System.out.println("Жизненный цикл: 2, внедрение зависимостей");
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public void initMethod(){
System.out.println("Жизненный цикл: 3, инициализация");
}
public void destroyMethod(){
System.out.println("Жизненный цикл: 5, разрушение");
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
'}';
}
}
Обратите внимание, что из initMethod() иdestroyMethod() вы можете настроить компонент для указания инициализации и уничтожения метода.
<!-- Используйте атрибут init-method, чтобы указать метод инициализации. -->
<!-- Используйте атрибут Destroy-method, чтобы указать метод уничтожения. -->
<bean id="user" class=" com.jie.ioc.model.User" init-method="initMethod" destroy-method="destroyMethod">
<property name="id" value="1001"/>
<property name="username" value="admin"/>
<property name="password" value="123456"/>
<property name="age" value="23"/>
</bean>
@Test
public void testLife() {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("bean.lifecycle.xml");
User bean = ac.getBean("user", User.class);
System.out.println("Жизненный цикл: 4, ввестиIOCконтейнер Получите компонент и используйте его");
System.out.println(bean);
ac.close();
}
Постпроцессор компонента добавит дополнительные операции до и после инициализации жизненного цикла.,Необходимо реализовать интерфейс BeanPostProcessor.,И настроил в IOCконтейнер,Необходимо обратить внимание на,Постпроцессор компонента не действует только на конкретный компонент.,ида будет выполнена для всех bean-компонентов в IOCконтейнере
Создайте постпроцессор компонента:
package com.jie.ioc.model;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @author Аджи 2416338031@qq.com
* @version 1.0
* @date 2023/9/3 15:34
*/
public class MyBeanProcessor implements BeanPostProcessor {
/**
* Выполняется перед инициализацией
*
* @param bean
* @param beanName
* @return: java.lang.Object
* @author Аджи 2416338031@qq.com
* @date: 2023/9/3 15:37
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("beanизпостпроцессор(Выполняется перед инициализацией)");
System.out.println("☆☆☆" + beanName + " = " + bean);
return bean;
}
/**
* Выполняется после инициализации
*
* @param bean
* @param beanName
* @return: java.lang.Object
* @author Аджи 2416338031@qq.com
* @date: 2023/9/3 15:37
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("beanизпостпроцессор(Выполняется после инициализации)");
System.out.println("★★★" + beanName + " = " + bean);
return bean;
}
}
Настройте постпроцессор в контейнере IOC:
<!-- Постпроцессор bean-компонента должен быть установлен в IOCконтейнер, чтобы он вступил в силу. -->
<bean id="myBeanProcessor" class="com.atguigu.spring6.process.MyBeanProcessor"/>
Результаты испытаний:
Продолжим демонстрацию. Многие из наших демонстраций основаны на управлении компонентами в xml. Итак, что мы собираемся продемонстрировать дальше? Он называется FactoryBean.
FactoryBeanSpring предоставляет общий механизм для интеграции сторонних платформ. В отличие от обычного изbean, настройте типизированный bean-компонент FactoryBean, получите его при получении bean-компонента и настройте из объекта этого класса в атрибуте daclass, метод idagetObject() из возвращаемого значения. Благодаря этому механизму применения Spring может помочь нам скрыть подробные процессы и утомительные детали сложных компонентов и показать нам только самый простой и краткий пользовательский интерфейс. Когда мы в будущем будем интегрировать Mybatis, Spring будет использовать механизм дапроходитьFactoryBean, который поможет нам создать объект SqlSessionFactoryBean.
package com.jie.ioc.model;
import org.springframework.beans.factory.FactoryBean;
/**
* Фабрика Бин
*
* @author Аджи 2416338031@qq.com
* @version 1.0
* @date 2023/9/3 15:48
*/
public class UserFactoryBean implements FactoryBean<User> {
/**
* Возвращаемый объект
*
* @return User
*/
@Override
public User getObject() throws Exception {
return new User();
}
/**
* Возвращаемый объекттип
*
* @return Class<User>
*/
@Override
public Class<?> getObjectType() {
return User.class;
}
}
<bean id="user" class="com.atguigu.spring6.bean.UserFactoryBean"></bean>
В ходе этого процесса он создал единственный экземпляр из пользовательского объекта, и мы настроили этот UserFactoryBean из этого объекта.
@Test
public void testUserFactoryBean(){
//Получаем IOCконтейнер
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.factorybean.xml");
User user = (User) ac.getBean("user");
System.out.println(user);
}
Автоматическая сборка: В соответствии с указанной стратегией из сопоставьте определенный bean-компонент в IOCконтейнере и автоматически присвойте значения атрибутам типа из класса или типа интерфейса, от которых зависит указанный избин.
Создать класс UserController.
package com.jie.ioc.controller;
/**
* пользовательский контроллер
*
* @author Аджи 2416338031@qq.com
* @date 2023/9/3 16:16
* @version 1.0
*/
public class UserController {
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
public void saveUser(){
userService.saveUser();
}
}
Создать интерфейс UserService
package com.jie.ioc.service;
/**
* Обслуживание пользователей
*
* @author Аджи 2416338031@qq.com
* @date 2023/9/3 16:16
* @version 1.0
*/
public interface UserService {
void saveUser();
}
Создайте класс UserServiceImpl для реализации интерфейса UserService.
package com.jie.ioc.service.impl;
import com.jie.ioc.service.UserService;
/**
* Обслуживание пользователей Класс реализации
*
* @author Аджи 2416338031@qq.com
* @date 2023/9/3 16:16
* @version 1.0
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void saveUser() {
userDao.saveUser();
}
}
Создать интерфейс UserDao
package com.jie.ioc.dao;
/**
* пользовательский интерфейс
*
* @author Аджи 2416338031@qq.com
* @version 1.0
* @date 2023/9/3 16:17
*/
public interface UserDao {
void saveUser();
}
Создайте класс UserDaoImpl для реализации интерфейса UserDao.
package com.jie.ioc.dao.impl;
import com.jie.ioc.dao.UserDao;
/**
* Класс реализации Userdao
*
* @author Аджи 2416338031@qq.com
* @version 1.0
* @date 2023/9/3 16:17
*/
public class UserDaoImpl implements UserDao {
@Override
public void saveUser() {
System.out.println("Сохранить успешно");
}
}
Используйте атрибут beanТегиautowire, чтобы установить эффект автоматического подключения. Автоматический метод сборки: по типу byType: сопоставьте совместимый типизбин в IOCконтейнере по типу и автоматически присваивайте значения атрибутам. Если в IOC нет совместимого typeizbean, который может присвоить значение атрибуту, атрибут не настроен, то есть значением по умолчанию является значение null. Если существует несколько совместимых типизбинов, которые могут присваивать значения свойствам в IOC, будет выдано исключение NoUniqueBeanDefinitionException.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Выполните автоматическую сборку в соответствии с типом -->
<bean id="userController" class="com.jie.ioc.controller.UserController" autowire="byType" />
<bean id="userService" class="com.jie.ioc.service.impl.UserServiceImpl" autowire="byType"/>
<bean id="userDao" class="com.jie.ioc.dao.impl.UserDaoImpl"/>
</beans>
Метод автоматической сборки: по Имя byName: автоматически собирает атрибут из атрибута из имени атрибута в качестве bean-компонента и сопоставляет соответствующий изbean в IOC-контейнере для назначения.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Автоматическая сборка по имени -->
<bean id="userController" class="com.jie.ioc.controller.UserController" autowire="byName"/>
<bean id="userService" class="com.jie.ioc.service.impl.UserServiceImpl" autowire="byName"/>
<bean id="userServiceImpl" class="com.jie.ioc.service.impl.UserServiceImpl" autowire="byName"/>
<bean id="userDao" class="com.jie.ioc.dao.impl.UserDaoImpl"/>
<bean id="userDaoImpl" class="com.jie.ioc.dao.impl.UserDaoImpl"/>
</beans>
③Тест
@Test
void testAutoWireByXml(){
ApplicationContext ac = new ClassPathXmlApplicationContext("autowire-xml.xml");
UserController userController = ac.getBean(UserController.class);
userController.saveUser();
}
от Java 5 Старт, Ява Добавлена поддержка аннотации (Annotation) из. Это можно понять как специальную отметку в коде аннотации. Его можно прочитать во время компиляции, загрузки класса и во время выполнения, а также выполнить соответствующую обработку. Разработчики могут встраивать дополнительную информацию в исходный код, не меняя исходный код и логику. Spring от 2.5 Начиная с версии предусмотрена полная поддержка технологии аннотации. Мы можем использовать аннотацию для реализации автоматической сборки и упрощения. Spring из XML конфигурация.
Шаги по реализации автоматической сборки в Spring проводят аннотацию следующим образом:
Метод построения следующий: Spring6-ioc-xml.
Представляем журнал модуля Spring-ioc-xml log4j2.xml
<dependencies>
<!--spring contextполагаться-->
<!--когда ты представляешьSpring Contextполагатьсяпосле,Указывает на то, что это будетSpringиз Базаполагатьсяпредставил-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.11</version>
</dependency>
<!--junit5тест-->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
</dependency>
<!--log4j2изполагаться-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
Spring Сборка аннотаций не используется по умолчанию Бин, так что нам нужно Spring из XML Конфигурациясередина,проходить context:component-scan элемент включен Spring Функция автоматического сканирования Beans. После включения этой функции Spring Автоматически сканирует указанный пакет (базовый пакет Настройки атрибута) и класс извсе в его подпакете, если класс используется. @Component аннотацию, соберите класс в контейнер.
Уведомление: Используется context:component-scan элемент включено Прежде чем использовать функцию автоматического сканирования, сначала необходимо XML Настройка метки первого уровня Добавить context Связано с ограничениями (пространством имен).
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
Ситуация 1. Самый простой метод сканирования.
<!-- Включить сканирование компонентов -->
<context:component-scan base-package="com.jie.annotation"/>
Таким образом, пока да построено на annotation извсе класса в своем подпакете, если класс используется @Component аннотацию, соберите класс в контейнер.
Случай 2. Укажите компонент, который необходимо исключить.
<context:component-scan base-package="com.jie.annotation">
<!-- тег context:exclude-filter: укажите правила исключения -->
<!--
тип: установите основание для исключения или включения
type="annotation", исключить согласно аннотации, задано в выражении для исключения изаннотациииз полного имени класса
type="assignable", исключить в соответствии с типом, заданным в выражении, чтобы исключить полное имя класса изтипиз
-->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<!--<context:exclude-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
</context:component-scan>
Сценарий 3: Сканировать только указанные компоненты
<context:component-scan base-package="com.jie.annotation" use-default-filters="false">
<!-- Тег context:include-filter: указывает на добавление правил на основе исходных правил сканирования. -->
<!-- Атрибут use-default-filters: ценитьfalse означает отключение правил сканирования по умолчанию. -->
<!-- На данный момент необходимо установить use-default-filters="false", поскольку правило по умолчанию сканирует все классы в указанном пакете. -->
<!--
тип: установите основание для исключения или включения
type="annotation", исключить согласно аннотации, задано в выражении для исключения изаннотациииз полного имени класса
type="assignable", исключить в соответствии с типом, заданным в выражении, чтобы исключить полное имя класса изтипиз
-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<!--<context:include-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
</context:component-scan>
Как правило, нам достаточно использовать первый.
Spring предоставляет следующие несколько аннотаций, которые можно аннотировать непосредственно в классах Java, чтобы определить их как Spring Beans.
аннотация | иллюстрировать |
---|---|
@Component | Аннотация используется для описания Spring серединаиз Бин, который является обобщенной концепцией, представляет собой только компонент (Бин) в контейнере и может использоваться на любом уровне приложения, например Service Слой, Дао слой и т. д. При его использовании просто отмечайте аннотацию соответствующего класса. |
@Repository | Аннотация используется для интеграции уровня доступа к данным (Dao слой) из класса идентифицируется как Spring серединаиз Бин, функция которого такая же, как @Component такой же. |
@Service | Аннотация обычно действует на бизнес-уровне (Сервис уровень), используемый для идентификации бизнес-уровня класса как Spring серединаиз Бин, функция которого такая же, как @Component такой же. |
@Controller | Аннотация обычно работает на уровне управления (например, Spring MVC). из Контроллер), используемый для идентификации класса уровня управления как Spring серединаиз Бин, функция которого такая же, как @Component такой же. |
Один @Autowiredаннотация,По умолчанию собирается в соответствии с типом。【по умолчаниюдаbyType】
Посмотреть исходный код:
В исходном коде вы можете увидеть обрамленную часть,Что это? Вы можете понимать это как аннотация Юань,Просто предоставлю аннотацию,Он содержит некоторые конкретные детали. Я посмотрел первую часть,Это называется @Target, он высказался, где эту аннотацию можно использовать.
Например, @Autowired можно использовать в:
Тогда второе место,Аннотация имеет обязательное свойство,Значение по умолчанию даtrue,Указывает, что при внедрении внедренный компонент должен существовать,Если его не существует, будет сообщено об ошибке. Если обязательный атрибут имеет значение false,Указывает, что не имеет значения, существует ли внедренный изBean или нет.,Если он существует, внедрите его,Слов не существует,Об ошибках также не сообщается.
Создать интерфейс UserDao
package com.jie.annotation.dao;
/**
* пользовательский интерфейс
*
* @author Аджи 2416338031@qq.com
* @version 1.0
* @date 2023/9/3 18:02
*/
public interface UserDao {
public void print();
}
Создайте реализацию UserDaoImpl.
package com.jie.annotation.dao.impl;
import com.jie.annotation.dao.UserDao;
import org.springframework.stereotype.Repository;
/**
* Класс реализации Userdao
*/
@Repository
public class UserDaoImpl implements UserDao {
@Override
public void print() {
System.out.println("Выполнение слоя Dao завершается");
}
}
Создать интерфейс UserService
package com.jie.annotation.service;
/**
* Обслуживание пользователейинтерфейс
*
* @author Аджи 2416338031@qq.com
* @date 2023/9/3 18:03
* @version 1.0
*/
public interface UserService {
public void out();
}
Создайте класс реализации UserServiceImpl.
package com.jie.annotation.service.impl;
import com.jie.annotation.dao.UserDao;
import com.jie.annotation.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Класс реализации уровня обслуживания
*
* @author Аджи 2416338031@qq.com
* @date 2023/9/3 18:03
* @version 1.0
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
@Override
public void out() {
userDao.print();
System.out.println("Выполнение сервисного уровня завершается");
}
}
Создать класс UserController
package com.jie.annotation.controller;
import com.jie.annotation.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
/**
* уровень контроллера
*
* @author Аджи 2416338031@qq.com
* @version 1.0
* @date 2023/9/3 18:04
*/
@Controller
public class UserController {
@Autowired
private UserService userService;
public void out() {
userService.out();
System.out.println("Выполнение уровня контроллера завершается.");
}
}
Тест первый
Измените класс UserServiceImpl.
Изменить класс UserController
Тест: успешный звонок
Измените класс UserServiceImpl.
Изменить класс UserController
Тест: успешный звонок
Измените класс UserServiceImpl.
Изменить класс UserController
Тест: успешный звонок
Измените класс UserServiceImpl.
тестпроходить
Если в конструкторе имеется только один параметр, @Autowiredаннотацию можно опустить.
иллюстрировать: А что если конструкторов несколько?
Результаты испытаний:
Добавить реализацию слоя dao
package com.jie.annotation.dao.impl;
import com.jie.annotation.dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoRedisImpl implements UserDao {
@Override
public void print() {
System.out.println("Redis Выполнение слоя Дао заканчивается");
}
}
тест:
В сообщении об ошибке говорится: Невозможно собрать, количество UserDao Beans равно 2.
Как решить эту проблему??Разумеется, требуется byName, и сборка выполняется по имени.
Измените класс UserServiceImpl.
@Resourceаннотация Внедрение свойств также может быть завершено。Чтоэтои**@Autowired**аннотациякакая разница?
@Resourceаннотация принадлежит пакету расширений JDK.,Значит дело не в JDK,Дополнительно необходимо ввести следующееполагаться:【Если даJDK8из, то никакого дополнительного Введения зависимостей не требуется. Для версий выше JDK11 или ниже JDK8 необходимо ввести следующие зависимости.】
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
Измените класс UserDaoImpl.
Измените класс UserServiceImpl.
тестпроходить
Измените класс UserDaoImpl.
Измените класс UserServiceImpl.
тестпроходить
Когда @Resourceаннотация используется без указания именииз,Также поиск по имени,Это имя — имя атрибута.
Изменить класс UserServiceImpl.,имя атрибута myUserDao1 не существует
Тестовое исключение
По ненормальной информации: Видимо, когда имя проведения не может найти из,Естественно, для внедрения будет запущен byType.,Вышеуказанная ошибка вызвана двумя классами реализации интерфейса UserDao. Поэтому при введении в соответствии с типом будет сообщено об ошибке.
Инъекцию @Resourceizset можно протестировать самостоятельно.
@Resourceаннотация: внедрение по имени по умолчанию,Если имя не указано, имя атрибута рассматривается как имя.,Когда не найден по имени,Будет происходить только внедрение по типу. когда byType вводится,Может быть только один компонент определенного типа.
Для полной разработки файлы конфигурации Spring больше не используются, а вместо файла конфигурации пишется класс конфигурации.
Тестовый класс