3. Подробное объяснение контейнера IOC Spring.
3. Подробное объяснение контейнера IOC Spring.

IoC да Инверсия управления из аббревиатуры,Переводится как «инверсия управления».,Это не технология,ида Что-то вродеДизайнерское мышление,важное правило изориентированного объектного программирования,Это может помочь нам в разработке слабосвязанных и более эффективных программ.

Spring проходить IoC-контейнеруправлятьвсе Java-объекты, инициализация и инициализация,Контролируйте зависимости между объектом и объектом。Мы будем IoC управляемый контейнером Java объект называется Spring Bean,Он использует ключевое слово new Создано Java. В объектах нет никакой разницы.

IoC-контейнерда Spring Один из наиболее важных основных компонентов структуры, он проходит через Spring Весь процесс от рождения до роста.

1. IoC-контейнер

1.1. Инверсия управления (Ио К).

  • Инверсия контроля – это мысль.
  • Инверсия управления используется для уменьшения связанности программ и улучшения масштабируемости программы.
  • Инверсия управления, инверсия изда чего?
    • Сдать права создания объектиз,Оставьте это в стороннем контейнере.
    • Передать право на защиту отношений между объектами,Оставьте это в стороннем контейнере.
  • Как реализовать идею инверсии управления?
    • DI(Dependency Инъекция): инъекция зависимостей

1.2. Внедрение зависимостей.

DI (Dependency Injection): внедрение зависимостей, реализующее идею инверсии управления.

Внедрение зависимостей:

  • Относится к внедрению атрибута зависимости объекта, определяющего конфигурацию в процессе создания объекта с помощью Spring.

Существует два распространенных метода реализации внедрения зависимостей:

  • Первый тип: установка впрыска
  • Второй тип: внедрение конструктора

Итак, в заключениеда:IOC Просто своего рода инверсия управляющей мысли, и DI да — это конкретная реализация IoCиз.

Управление компонентами говорит изда: создание объекта Beanобъекта и атрибут назначения объекта Bean (или связь между объектом Bean из обслуживания).

1.3. Реализация IoC-контейнера весной.

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 в домене.

2. Управление компонентами на основе XML

2.1 Создайте подмодуль Spring6-ioc-xml

①Сборка модулей

Способ строительства: весенний.

②Введение файлов конфигурации

Представляем файлы конфигурации модуля Spring-First: beans.xml, log4j2.xml.

③Добавить зависимости

Язык кода:javascript
копировать
<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

2.2 Эксперимент 1: Получение бобов

①Метод 1: Получить на основе идентификатора

потому что id Атрибут указан bean из уникального идентификатора, поэтому согласно bean Теги id Свойства могут точно получить объект-компонент. Передний Мы рождаемся Для начала используйте этот метод: из.

②Метод 2: на основе типа
③Метод 3: В зависимости от идентификатора и типа
④ Регионы, требующие осторожности

когда на основетипКогда получаешь боб,ТребоватьIOCконтейнеруказано втипизЕсть и может быть только один боб

Если в контейнере IOC настроено всего два:

Затем мы получаем Bean в зависимости от типа.

Будет выброшено исключение.

⑤Расширить знания

Если класс компонента реализует интерфейс, можно ли получить компонент на основе типа интерфейса?

Да, предполагается, что дабеан единственный

Язык кода:javascript
копировать
package com.jie.ioc.service;

/**
 * @Auther: Administrator
 * @Date: 2023/08/30/15:38
 * @Description:
 */
public interface HelloWorldService {

     void run();

}
Язык кода:javascript
копировать
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-компоненты на основе типа интерфейса?

Нет, потому что бин не уникален

Язык кода:javascript
копировать
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 Левая и правая операции оператора из должны иметь отношения наследования или реализации.

2.3 Эксперимент 2: внедрение установщика зависимостей

①Создать класс учеников
Язык кода:javascript
копировать
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 + '\'' +
                '}';
    }

}
②Присвоение значений свойствам при настройке beans
Язык кода:javascript
копировать
<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>
③Тест
Язык кода:javascript
копировать
@Test
public void testDIBySet(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    Student studentOne = ac.getBean("studentOne", Student.class);
    System.out.println(studentOne);
}

2.4 Эксперимент 3. Внедрение зависимостей в конструктор

①Добавьте параметризованную конструкцию в класс Student.
Язык кода:javascript
копировать
public Student(Integer id, String name, Integer age, String sex) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.sex = sex;
}
②Настройка bean-компонентов

spring-di.xml

Язык кода:javascript
копировать
  <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 также имеет два атрибута, которые дополнительно описывают параметры конструктора:

  • Атрибут индекса: Укажите расположение параметра индекс (начиная с от0)
  • Атрибут имени: указывает имя параметра
③Тест
Язык кода:javascript
копировать
@Test
public void testDIByConstructor(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
    Student studentOne = ac.getBean("studentTwo", Student.class);
    System.out.println(studentOne);
}

2.5 Эксперимент 4: обработка специальных значений

①Литеральное присвоение

Что в буквальном смысле? int a = 10; Объявить переменную a,инициализирован до 10,В настоящее время a не представляет букву a.,идакак переменная по имени。когда мы цитируемaизкогда,Фактически мы получаем значение да10. Если ада в кавычках из: ‘a’, то это теперь не переменная, а представляет собой саму букву а, которая является литералом да. Следовательно, литерал не расширяет значение, мы видим данные только сами по себе.

Язык кода:javascript
копировать
<!-- При использовании атрибута value для присвоения значения атрибуту bean-компонента Spring будет рассматривать атрибут value как литерал. -->
<property name="name" value="Чжан Сан"/>
②нулевое значение
Язык кода:javascript
копировать
<property name="name">
    <null />
</property>

Уведомление:

Язык кода:javascript
копировать
<property name="name" value="null"></property>

Вышеупомянутый метод записи представляет собой строку null, присвоенную имени.

③ XML-объект
Язык кода:javascript
копировать
<!-- меньше, чем войтиXMLиспользуется для определения в документе Тегиначинать,нельзя использовать случайно -->
<!-- Решение 1. Вместо этого используйте сущности XML -->
<property name="expression" value="a &lt; b"/>
④Раздел CDATA
Язык кода:javascript
копировать
<property name="expression">
    <!-- Решение второе: используйте раздел CDATA -->
    <!-- изC в CDATA представляет собой символ, да текст, обозначение символа, CDATA представляет собой текстовые данные -->
    <!-- Когда анализатор XML видит раздел CDATA, он знает, что это обычный текст, и не будет анализировать его как тег или атрибут XML. -->
    <!-- Таким образом, вы можете писать любые символы в разделе CDATA. -->
    <value><![CDATA[a < b]]></value>
</property>

2.6 Эксперимент 5: Присвоение значений атрибутам типа объекта.

①Создать класс класса Clazz
Язык кода:javascript
копировать
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:

Язык кода:javascript
копировать
private Clazz clazz;

public Clazz getClazz() {
	return clazz;
}

public void setClazz(Clazz clazz) {
	this.clazz = clazz;
}
Метод 1: Ссылка на внешние bean-компоненты

Настройте Clazzтипизбин:

Язык кода:javascript
копировать
<bean id="clazzOne" class="com.jie.ioc.model.Clazz">
        <property name="clazzId" value="1111"/>
        <property name="clazzName" value="Богатство денежного класса"/>
</bean>

Присвойте значение атрибуту изclazz в Student:

Язык кода:javascript
копировать
<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-компонента на основе это для присвоения значения.

Метод 2: Внутренние bean-компоненты
Язык кода:javascript
копировать
<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>

Результаты испытаний:

Способ 3: Каскадное присвоение атрибутов
Язык кода:javascript
копировать
<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>

Результаты испытаний:

2.7 Эксперимент 6: Присвоение значений атрибутам типа массива

①Изменить класс «Студент».

Добавьте следующий код в класс Student:

Язык кода:javascript
копировать
private String[] hobbies;

public String[] getHobbies() {
    return hobbies;
}

public void setHobbies(String[] hobbies) {
    this.hobbies = hobbies;
}
②Настройка bean-компонентов
Язык кода:javascript
копировать
<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.

2.8 Эксперимент 7: Присвоение значений атрибутам типа коллекции

①Присвоение значений атрибутам типа коллекции List.

Добавьте следующий код в класс Clazz:

Язык кода:javascript
копировать
private List<Student> students;

public List<Student> getStudents() {
    return students;
}

public void setStudents(List<Student> students) {
    this.students = students;
}

Настройте bean-компоненты:

Язык кода:javascript
копировать
 <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.

②Присвоение значений атрибутам типа коллекции карт.

Создайте класс учителя Учитель:

Язык кода:javascript
копировать
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:

Язык кода:javascript
копировать
private Map<String, Teacher> teacherMap;

public Map<String, Teacher> getTeacherMap() {
    return teacherMap;
}

public void setTeacherMap(Map<String, Teacher> teacherMap) {
    this.teacherMap = teacherMap;
}

Настройте bean-компоненты:

Язык кода:javascript
копировать
<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, мы должны ввести соответствующее пространство имен.

Язык кода:javascript
копировать
<?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">
Язык кода:javascript
копировать
<!--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>

Результаты испытаний:

2.9 Эксперимент 8: пространство имен p

Во-первых, позвольте мне объяснить, что такое пространство имен или пространство имен.

Внимание всем, в «Эксперимент 7: Присвоение значений свойствам типа коллекции» серединаиз Справочная коллекция Во время демонстрации. мы добавили

эта часть,его название да util, Добавлю сюда еще один.

Например, посмотрите, как я сейчас пишу вилку xmlns.,Внимание всем,Сейчас на этом ярлыке,Имя его атрибута да или да называется xmlns. Если вы сейчас так напишете, то это точно неправильно!

Поскольку у вас не может быть двух свойств с одинаковым именем, мы можем добавить раздел.

Например, добавление буквы P называется пространством имен. Вы можете просто понять, что это делается для того, чтобы избежать конфликтов в определениях атрибутов в тегах. Затем добавьте после него такой адрес и используйте его для завершения процесса внедрения после его завершения.

После завершения давайте проведем быстрый тест, чтобы опробовать этот эффект.

2.10 Эксперимент 9. Знакомство с внешними файлами свойств

Далее мы научимся вводить файлы внешних свойств.

Позвольте мне сначала поговорить об этом Импортировать файлы внешних свойствизнеобходимость,илиэтоиз Сценарии примененияда Как насчет этого。Внимание всем,Просто дая теперь наделен различными атрибутами,Мы все были записаны почти в одном файле.

Если, скажем, вам ввели только один компонент, это не имеет значения. Но в большинстве случаев у нас не может быть только одного боба.

В это время все обнаружили, что у нас здесь много бобов.,Есть много чего, что стоит ввести. Тогда нам придется внести некоторые изменения,Требуется дополнительное обслуживание,Особенно неудобно, если да не да.

На практике мы обычно делаем это так,Поместите некоторые конкретные и фиксированные значения во внешний файл.,Затем введите внешний файл и внедрите его внутрь.

Это более распространено, чем изменение базы данных. Например, наши данные имеют имя пользователя.,Есть пароль,Есть такая информация, как адрес. Тогда давайте напишем внешний файл,Импортируйте файл,Введите его внутрь,Это облегчает нам выполнение технического обслуживания. Если я хочу изменить базу данных сейчас,Тогда давайте изменим мой внешний файл. иspringиз вставить файл,Тогда нам не нужно его модифицировать,Это основное требование.

Далее займемся реализацией.

①Добавить зависимости
Язык кода:javascript
копировать
<!-- Драйвер 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>
②Создать файл внешних свойств.
Язык кода:javascript
копировать
jdbc.user=root
jdbc.password=ajie
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.driver=com.mysql.cj.jdbc.Driver
③Введение файла свойств

Введение контекстного пространства имен

Язык кода:javascript
копировать
<?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>
Язык кода:javascript
копировать
<!-- Импортировать файлы внешних свойств -->
<context:property-placeholder location="classpath:jdbc.properties"/>

Уведомление: Используется context:property-placeholder Прежде чем элемент загрузит функцию файла конфигурации аутсорсинга, его сначала необходимо XML Настройка метки первого уровня Добавить context Связано с ограничениями.

④Настроить bean-компоненты
Язык кода:javascript
копировать
<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>
⑤Тест
Язык кода:javascript
копировать
@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);
}

2.11 Эксперимент 10: Область применения компонента

①Концепция

существоватьSpringсередина Можетпроходить КонфигурацияbeanТегиscopeатрибуты приходятобозначениеbeanиз Объем,каждыйценитьзначение Присоединяйтесь к таблице ниже:

ценить

значение

Время создавать объектиз

синглтон (по умолчанию)

В IOCконтейнере этот bean-объект всегда является единственным экземпляром.

Когда контейнер IOC инициализируется

prototype

Этот компонент имеет несколько экземпляров в контейнере IOC.

Когда получаешь боб

Если да имеет несколько других областей в среде WebApplicationContext (но не часто используемых):

ценить

значение

request

Действительно в пределах области запроса

session

Действительно в пределах сеанса

②Создать пользователя класса
Язык кода:javascript
копировать
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 +
                '}';
    }
}
③Настройка bean-компонентов
Язык кода:javascript
копировать
<?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>
④Тест

Да Шаблон с несколькими экземплярами,Создано изда двух разных изобъектов,Давайте попробуем перейти на синглтон.

Язык кода:javascript
копировать
@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);
}

2.12 Эксперимент 11: жизненный цикл компонента

Что такое жизненный цикл? Если говорить о жизненном цикле человека,Далее идет процесс от рождения до смерти даот. Если мы теперь поговорим о жизненном цикле Bean,Это означает создание объекта для уничтожения из процесса.,Это называется жизненным циклом.

①Процесс жизненного цикла конкретного компонента
  • создание beanобъекта (вызов конструктора без аргументов)
  • Установить свойства для bean-объекта
  • постпроцессор bean-компонента (перед инициализацией)
  • Инициализация bean-объекта (необходимо указать метод инициализации при настройке bean-компонента)
  • bean-постпроцессор (после инициализации)
  • beanобъект готов к использованию
  • уничтожение объекта bean (необходимо указать метод уничтожения при настройке bean-компонента)
  • Контейнер МОКЗакрыть
②Изменить класс пользователя
Язык кода:javascript
копировать
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() вы можете настроить компонент для указания инициализации и уничтожения метода.

③Настройка bean-компонентов
Язык кода:javascript
копировать
<!-- Используйте атрибут 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>
④Тест
Язык кода:javascript
копировать
@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контейнере

Создайте постпроцессор компонента:

Язык кода:javascript
копировать
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:

Язык кода:javascript
копировать
<!-- Постпроцессор bean-компонента должен быть установлен в IOCконтейнер, чтобы он вступил в силу. -->
<bean id="myBeanProcessor" class="com.atguigu.spring6.process.MyBeanProcessor"/>

Результаты испытаний:

2.13 Эксперимент 12: FactoryBean

Продолжим демонстрацию. Многие из наших демонстраций основаны на управлении компонентами в xml. Итак, что мы собираемся продемонстрировать дальше? Он называется FactoryBean.

①Введение

FactoryBeanSpring предоставляет общий механизм для интеграции сторонних платформ. В отличие от обычного изbean, настройте типизированный bean-компонент FactoryBean, получите его при получении bean-компонента и настройте из объекта этого класса в атрибуте daclass, метод idagetObject() из возвращаемого значения. Благодаря этому механизму применения Spring может помочь нам скрыть подробные процессы и утомительные детали сложных компонентов и показать нам только самый простой и краткий пользовательский интерфейс. Когда мы в будущем будем интегрировать Mybatis, Spring будет использовать механизм дапроходитьFactoryBean, который поможет нам создать объект SqlSessionFactoryBean.

②Создать пользователя классаFactoryBean
Язык кода:javascript
копировать
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-компонентов
Язык кода:javascript
копировать
<bean id="user" class="com.atguigu.spring6.bean.UserFactoryBean"></bean>
④Тест

В ходе этого процесса он создал единственный экземпляр из пользовательского объекта, и мы настроили этот UserFactoryBean из этого объекта.

Язык кода:javascript
копировать
@Test
public void testUserFactoryBean(){
    //Получаем IOCконтейнер
    ApplicationContext ac = new ClassPathXmlApplicationContext("bean.factorybean.xml");
    User user = (User) ac.getBean("user");
    System.out.println(user);
}

2.14 Эксперимент 13: Автоматическая сборка на основе xml

Автоматическая сборка: В соответствии с указанной стратегией из сопоставьте определенный bean-компонент в IOCконтейнере и автоматически присвойте значения атрибутам типа из класса или типа интерфейса, от которых зависит указанный избин.

①Имитация сцены

Создать класс UserController.

Язык кода:javascript
копировать
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

Язык кода:javascript
копировать
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.

Язык кода:javascript
копировать
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

Язык кода:javascript
копировать
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.

Язык кода:javascript
копировать
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-компонентов

Используйте атрибут beanТегиautowire, чтобы установить эффект автоматического подключения. Автоматический метод сборки: по типу byType: сопоставьте совместимый типизбин в IOCконтейнере по типу и автоматически присваивайте значения атрибутам. Если в IOC нет совместимого typeizbean, который может присвоить значение атрибуту, атрибут не настроен, то есть значением по умолчанию является значение null. Если существует несколько совместимых типизбинов, которые могут присваивать значения свойствам в IOC, будет выдано исключение NoUniqueBeanDefinitionException.

Язык кода:javascript
копировать
<?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-контейнере для назначения.

Язык кода:javascript
копировать
<?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>

③Тест

Язык кода:javascript
копировать
@Test
void testAutoWireByXml(){
    ApplicationContext ac = new ClassPathXmlApplicationContext("autowire-xml.xml");
    UserController userController = ac.getBean(UserController.class);
    userController.saveUser();
}

3. Управление компонентами на основе аннотаций (☆)

от Java 5 Старт, Ява Добавлена ​​поддержка аннотации (Annotation) из. Это можно понять как специальную отметку в коде аннотации. Его можно прочитать во время компиляции, загрузки класса и во время выполнения, а также выполнить соответствующую обработку. Разработчики могут встраивать дополнительную информацию в исходный код, не меняя исходный код и логику. Spring от 2.5 Начиная с версии предусмотрена полная поддержка технологии аннотации. Мы можем использовать аннотацию для реализации автоматической сборки и упрощения. Spring из XML конфигурация.

Шаги по реализации автоматической сборки в Spring проводят аннотацию следующим образом:

  1. Введение зависимостей
  2. Включить сканирование компонентов
  3. Определите Bean, используя аннотацию
  4. внедрение зависимостей

3.1 Создайте подмодуль Spring6-ioc-annotation

①Сборка модулей

Метод построения следующий: Spring6-ioc-xml.

②Введение файлов конфигурации

Представляем журнал модуля Spring-ioc-xml log4j2.xml

③Добавить зависимости
Язык кода:javascript
копировать
<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>

3.2 Включите сканирование компонентов

Spring Сборка аннотаций не используется по умолчанию Бин, так что нам нужно Spring из XML Конфигурациясередина,проходить context:component-scan элемент включен Spring Функция автоматического сканирования Beans. После включения этой функции Spring Автоматически сканирует указанный пакет (базовый пакет Настройки атрибута) и класс извсе в его подпакете, если класс используется. @Component аннотацию, соберите класс в контейнер.

Уведомление: Используется context:component-scan элемент включено Прежде чем использовать функцию автоматического сканирования, сначала необходимо XML Настройка метки первого уровня Добавить context Связано с ограничениями (пространством имен).

Язык кода:javascript
копировать
 <?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. Самый простой метод сканирования.

Язык кода:javascript
копировать
<!-- Включить сканирование компонентов -->
<context:component-scan base-package="com.jie.annotation"/>

Таким образом, пока да построено на annotation извсе класса в своем подпакете, если класс используется @Component аннотацию, соберите класс в контейнер.

Случай 2. Укажите компонент, который необходимо исключить.

Язык кода:javascript
копировать
<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: Сканировать только указанные компоненты

Язык кода:javascript
копировать
<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>

Как правило, нам достаточно использовать первый.

3.3 Определение компонентов с помощью аннотаций

Spring предоставляет следующие несколько аннотаций, которые можно аннотировать непосредственно в классах Java, чтобы определить их как Spring Beans.

аннотация

иллюстрировать

@Component

Аннотация используется для описания Spring серединаиз Бин, который является обобщенной концепцией, представляет собой только компонент (Бин) в контейнере и может использоваться на любом уровне приложения, например Service Слой, Дао слой и т. д. При его использовании просто отмечайте аннотацию соответствующего класса.

@Repository

Аннотация используется для интеграции уровня доступа к данным (Dao слой) из класса идентифицируется как Spring серединаиз Бин, функция которого такая же, как @Component такой же.

@Service

Аннотация обычно действует на бизнес-уровне (Сервис уровень), используемый для идентификации бизнес-уровня класса как Spring серединаиз Бин, функция которого такая же, как @Component такой же.

@Controller

Аннотация обычно работает на уровне управления (например, Spring MVC). из Контроллер), используемый для идентификации класса уровня управления как Spring серединаиз Бин, функция которого такая же, как @Component такой же.

3.4 Эксперимент 1: @Autowired-инъекция

Один @Autowiredаннотация,По умолчанию собирается в соответствии с типом。【по умолчаниюдаbyType】

Посмотреть исходный код:

В исходном коде вы можете увидеть обрамленную часть,Что это? Вы можете понимать это как аннотация Юань,Просто предоставлю аннотацию,Он содержит некоторые конкретные детали. Я посмотрел первую часть,Это называется @Target, он высказался, где эту аннотацию можно использовать.

Например, @Autowired можно использовать в:

  • По способу строительства
  • метод
  • Ката посещение
  • Атрибуты
  • аннотацияначальство

Тогда второе место,Аннотация имеет обязательное свойство,Значение по умолчанию даtrue,Указывает, что при внедрении внедренный компонент должен существовать,Если его не существует, будет сообщено об ошибке. Если обязательный атрибут имеет значение false,Указывает, что не имеет значения, существует ли внедренный изBean или нет.,Если он существует, внедрите его,Слов не существует,Об ошибках также не сообщается.

① Сценарий 1: Внедрение атрибутов

Создать интерфейс UserDao

Язык кода:javascript
копировать
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.

Язык кода:javascript
копировать
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

Язык кода:javascript
копировать
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.

Язык кода:javascript
копировать
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

Язык кода:javascript
копировать
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("Выполнение уровня контроллера завершается.");
    }

}

Тест первый

②Сценарий 2: установка впрыска

Измените класс UserServiceImpl.

Изменить класс UserController

Тест: успешный звонок

③Сценарий 3: Внедрение метода конструктора

Измените класс UserServiceImpl.

Изменить класс UserController

Тест: успешный звонок

④Сценарий 4: Внедрение в формальные параметры

Измените класс UserServiceImpl.

Изменить класс UserController

Тест: успешный звонок

⑤Сценарий 5: Только один конструктор, без аннотаций.

Измените класс UserServiceImpl.

тестпроходить

Если в конструкторе имеется только один параметр, @Autowiredаннотацию можно опустить.

иллюстрировать: А что если конструкторов несколько?

Результаты испытаний:

⑥Сценарий 6: Комбинация аннотации @Autowired и аннотации @Qualifier.

Добавить реализацию слоя dao

Язык кода:javascript
копировать
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.

Подвести итог
  • @Autowiredаннотацию можно найти в: Атрибуты, По способу строительства、Метод и параметры конструктора、setterметод。
  • Когда имеется только один конструктор с параметрами из,@Autowiredаннотацию можно опустить.()
  • @Autowiredаннотация по умолчанию вводится в соответствии с типом. Если вы хотите сделать инъекцию на основе имени,Необходимо использовать вместе с @Qualifierаннотация.

3.5 Эксперимент 2: внедрение @ресурсов

@Resourceаннотация Внедрение свойств также может быть завершено。Чтоэтои**@Autowired**аннотациякакая разница?

  • Пакет расширения @ResourceаннотацияJDK,Другими словами, говорят, что он является частью JDK. Итак, стандартная аннотация аннотации,Более универсальный. (Установлено в стандарте JSR-250. Тип аннотации. Предложение спецификации JSRдаJava.)
  • @Autowiredаннотацияда Сам фреймворк Spring из.
  • @Resourceаннотация по умолчанию собирается по имени по имени.,Когда имя не указано,Используйте имя свойства в качестве имени. Если имя_приведения не может быть найдено, сборка проводитьтиппотипу будет запущена автоматически.
  • @Autowiredаннотация По умолчанию собирается в соответствии с типомbyType,Если вы хотите собрать по имени,Необходимо использовать вместе с @Qualifierаннотация.
  • @Resourceаннотацияиспользоватьсуществовать Атрибуты、setterметод。
  • @Autowiredаннотацияиспользоватьсуществовать Атрибуты、setterметод、По способу строительство, параметры метода конструктора.

@Resourceаннотация принадлежит пакету расширений JDK.,Значит дело не в JDK,Дополнительно необходимо ввести следующееполагаться:【Если даJDK8из, то никакого дополнительного Введения зависимостей не требуется. Для версий выше JDK11 или ниже JDK8 необходимо ввести следующие зависимости.

Язык кода:javascript
копировать
<dependency>
    <groupId>jakarta.annotation</groupId>
    <artifactId>jakarta.annotation-api</artifactId>
    <version>2.1.1</version>
</dependency>
① Сценарий 1: Введение по имени

Измените класс UserDaoImpl.

Измените класс UserServiceImpl.

тестпроходить

②Сценарий 2: Инъекция неизвестного имени

Измените класс UserDaoImpl.

Измените класс UserServiceImpl.

тестпроходить

Когда @Resourceаннотация используется без указания именииз,Также поиск по имени,Это имя — имя атрибута.

③Сценарий 3 Другие ситуации

Изменить класс UserServiceImpl.,имя атрибута myUserDao1 не существует

Тестовое исключение

По ненормальной информации: Видимо, когда имя проведения не может найти из,Естественно, для внедрения будет запущен byType.,Вышеуказанная ошибка вызвана двумя классами реализации интерфейса UserDao. Поэтому при введении в соответствии с типом будет сообщено об ошибке.

Инъекцию @Resourceizset можно протестировать самостоятельно.

Подвести итог

@Resourceаннотация: внедрение по имени по умолчанию,Если имя не указано, имя атрибута рассматривается как имя.,Когда не найден по имени,Будет происходить только внедрение по типу. когда byType вводится,Может быть только один компонент определенного типа.

3.6 Разработка полной аннотации Spring

Для полной разработки файлы конфигурации Spring больше не используются, а вместо файла конфигурации пишется класс конфигурации.

Тестовый класс

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose