当前位置: 首页 > article >正文

十二:java web(4)-- Spring核心基础

目录

创建项目

Spring 核心基础

Spring 容器

Spring 容器的作用

Spring 容器的工作流程

Bean

Bean 的生命周期

IOC(控制反转)与依赖注入(DI)

控制反转的概念

依赖注入的几种方式(构造器注入、Setter 注入、接口注入)

构造器注入:依赖对象通过类的构造器传入。

基于 XML 的构造器注入

基于注解的构造器注入

Setter 注入:通过 Setter 方法将依赖注入到对象中。

Setter 注入的基本原理

Setter 注入的优缺点

Spring 容器工作原理

案例实现:

Spring 配置文件(基于 XML)

使用 Java 配置类

接口注入:这种方式不常见,是通过接口方法将依赖注入,一般不推荐。

Spring Bean 的生命周期

Spring Bean 的配置

基于 XML 的配置

XML 配置文件的基础结构

定义 Bean

基本的 Bean 配置

Bean 的作用域

注入依赖

 构造器注入

 属性注入(Setter 注入)

​​​​​​​集合注入

​​​​​​​​​​​​​​注入 Map

注入 Properties

自动装配(Autowiring)

​​​​​​​​​​​​​​加载 Bean 配置文件

基于 Java 配置类的配置

Spring AOP(面向切面编程)

AOP 概念与用途

AOP 切入点和通知类型(前置通知、后置通知、环绕通知等)

使用 @Aspect 注解配置 AOP


创建项目 方便跟着练习

   创建一个基本的maven项目

    <dependencies>
        <!-- Spring Context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.10</version>
        </dependency>

        <!-- Spring Beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.3.10</version>
        </dependency>
    </dependencies>
package com.lirui.example;

public class UserRepository {
    public void save() {
        System.out.println("1111111111");
    }
}
package com.lirui.example;

public class UserService {
    private final UserRepository userRepository;

    // 构造器注入
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void saveUser() {
        userRepository.save();
    }
}
package com.lirui;

import com.lirui.example.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        // 加载 Spring 配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 获取 userService Bean
        UserService userService = context.getBean("userService", UserService.class);

        // 调用方法
        userService.saveUser();
    }
}
<?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">

    <!--    applicationContext.xml 是 Spring 框架中的配置文件,
    通常用于定义 Spring IoC(控制反转)容器中的 Bean 配置和管理。
    这个文件主要用于将 Spring 的配置项和组件描述清楚,
    告知 Spring 容器如何实例化、配置和管理应用程序中的各种对象(Bean)。
    它是 Spring 配置的传统方式之一(除了注解和 Java 配置类)。-->
    <!-- 定义 UserRepository Bean -->
    <bean id="userRepository" class="com.lirui.example.UserRepository"/>

    <!-- 定义 UserService Bean,注入 userRepository -->
    <bean id="userService" class="com.lirui.example.UserService">
        <constructor-arg ref="userRepository"/>
    </bean>

</beans>

 

Spring 核心基础

  • Spring 容器

    • Spring 容器是 Spring 框架的核心组件之一。

    • Spring 容器的作用

      • 创建和管理 Bean:Spring 容器根据配置文件(如 XML 配置、注解或 Java 配置类)创建 Java 对象,并通过依赖注入(DI)管理这些对象的生命周期和依赖关系。

      • 控制反转(IoC):Spring 容器负责对象的创建、配置和管理,应用程序中的对象不再直接创建和管理依赖项,容器完成这些任务。这种方式称为控制反转(Inversion of Control, IoC)。

      • 提供依赖注入(DI):容器自动将所需的依赖注入到对象中,使得对象之间的耦合度降低,从而提高代码的灵活性和可维护性。

    • Spring 容器的工作流程

      • 加载配置文件:Spring 容器首先加载配置文件或注解配置,解析其中的 Bean 定义。

      • 创建 Bean 实例:根据配置,Spring 容器创建 Bean 实例,并进行初始化。

      • 依赖注入:容器自动将其他 Bean(依赖)注入到当前 Bean 中,通常通过构造器注入、Setter 注入或字段注入。

      • Bean 的使用:应用程序获取 Bean 并调用其方法。

      • 销毁 Bean:当容器关闭时,容器销毁 Bean 实例,执行清理操作。

    • Bean

      • Bean 是指由 Spring 容器管理的对象

    • Bean 的生命周期

      • 实例化:Spring 容器根据配置或注解定义的 Bean 类创建对象实例。

      • 依赖注入:容器将所需的依赖项注入到 Bean 的属性中。依赖可以是通过构造器注入、Setter 注入或字段注入。

      • 初始化:在 Bean 完成依赖注入后,容器会调用 Bean 的初始化方法(如果定义了)。

      • 使用:Bean 可以被应用程序使用(通过 Spring 容器获取)。

      • 销毁:当容器关闭时,容器会销毁 Bean,执行销毁回调方法(如果定义了)。

  • IOC(控制反转)与依赖注入(DI)

    • 控制反转的概念

      • 控制反转(Inversion of Control,简称 IOC)是 Spring 的核心概念,指的是将对象的创建和依赖关系的管理交由容器(如 Spring 容器)来处理,而不是由对象自己来完成。这种反转是通过依赖注入(DI)实现的,能减少代码耦合,提高可测试性和灵活性。

        在传统的 Java 编程中,对象依赖于其他对象通常是通过 new 关键字来创建,这会导致类之间紧密耦合。而通过 IOC,容器负责管理这些依赖关系,类之间的耦合度更低。

    • 依赖注入的几种方式(构造器注入、Setter 注入、接口注入)

      • 构造器注入:依赖对象通过类的构造器传入。
        • 基于 XML 的构造器注入
          • 在 Spring 中,可以通过 bean<constructor-arg> 元素来实现构造器注入。这里的 constructor-arg 元素用于传递构造函数的参数,Spring 会根据配置的顺序自动匹配构造器的参数。

          • <constructor-arg> 标签可以通过 valueref 属性来传递构造函数的参数。它们的作用如下:

            • value: 用于传递简单的常量值,如字符串、数字、布尔值等。这通常用于基本类型或字符串类型的构造参数。

            • ref: 用于传递引用类型的参数,通常用于传递其他 bean 的引用。如果构造函数参数是另一个 bean 的引用,使用 ref 属性。

          • package com.lirui.car;
            
            public class Car {
                private Engine engine;
            
                public Car(Engine engine) {
                    this.engine = engine;
                }
            
                public void drive() {
                    System.out.println("车使用" + engine.getType()+engine.getHorsepower());
                }
            }
            
            
            
            package com.lirui.car;
            
            public class Engine {
                private String type;
                private int horsepower;
            
                public Engine(String type,int horsepower) {
                    this.type = type;
                    this.horsepower = horsepower;
                }
            
                public String getType() {
                    return type;
                }
                public int getHorsepower() {
                    return horsepower;
                }
            }
            
            
            package com.lirui.car;
            
            import org.springframework.context.ApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;
            
            public class Main {
            
                public static void main(String[] args) {
                    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
                    Car car = context.getBean("ca", Car.class);
                    car.drive();
                }
            }
            
            
            <?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">
            
                <!--    applicationContext.xml 是 Spring 框架中的配置文件,
                通常用于定义 Spring IoC(控制反转)容器中的 Bean 配置和管理。
                这个文件主要用于将 Spring 的配置项和组件描述清楚,
                告知 Spring 容器如何实例化、配置和管理应用程序中的各种对象(Bean)。
                它是 Spring 配置的传统方式之一(除了注解和 Java 配置类)。-->
                <!-- 定义 UserRepository Bean -->
                <bean id="userRepository" class="com.lirui.example.UserRepository"/>
            
                <!-- 定义 UserService Bean,注入 userRepository -->
                <bean id="userService" class="com.lirui.example.UserService">
                    <constructor-arg ref="userRepository"/>
                </bean>
            
            
                <bean id="V8en" class="com.lirui.car.Engine">
                    <constructor-arg value="V8"/>
                    <constructor-arg value="500"/>
                </bean>
            
                <bean id="V6en" class="com.lirui.car.Engine">
                    <constructor-arg value="V6"/>
                    <constructor-arg value="200"/>
                </bean>
            
                <bean id="ca" class="com.lirui.car.Car">
                    <constructor-arg ref="V6en"/>
                </bean>
            
            </beans>
            

        • 基于注解的构造器注入
          • 在 Spring 3.0 及以后的版本中,可以通过 @Autowired 注解来实现构造器注入,Spring 会自动根据构造函数参数类型来选择合适的 bean。
          • package com.lirui.car;
            
            
            import org.springframework.context.annotation.ComponentScan;
            import org.springframework.context.annotation.Configuration;
            import org.springframework.context.annotation.PropertySource;
            
            @Configuration
            @ComponentScan(basePackages = "com.lirui.car")
            @PropertySource("classpath:application.properties")
            public class AppConfig {
            }
            
            
            
            package com.lirui.car;
            
            
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.stereotype.Component;
            
            @Component
            public class Car {
                private Engine engine;
            
            
                @Autowired
                public Car(Engine engine) {
                    this.engine = engine;
                }
            
                public void drive() {
                    System.out.println("车使用" + engine.getType()+engine.getHorsepower());
                }
            }
            
            
            package com.lirui.car;
            
            
            import org.springframework.beans.factory.annotation.Value;
            import org.springframework.stereotype.Component;
            
            @Component
            public class Engine {
                private String type;
                private int horsepower;
            
                public Engine(@Value("${car.engine.type}")String type,@Value("${car.engine.horsepower}") int horsepower) {
                    this.type = type;
                    this.horsepower = horsepower;
                }
            
                public String getType() {
                    return type;
                }
                public int getHorsepower() {
                    return horsepower;
                }
            }
            
            
            package com.lirui.car;
            
            import org.springframework.context.ApplicationContext;
            import org.springframework.context.annotation.AnnotationConfigApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;
            
            public class Main {
            
                public static void main(String[] args) {
                    ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
                    Car car = context.getBean(Car.class);
                    car.drive();
                }
            }
            
            
            #application.properties
            car.engine.type=V8
            car.engine.horsepower=200
            
            
          • AppConfig.java(配置类)

            • @Configuration
              • 作用:标识该类是一个 Spring 配置类,相当于传统的 XML 配置文件。
              • 解释:Spring 会通过这个类来定义和配置 Spring 容器中的 Bean。它指定了类中的方法可以用于生成 Bean 配置。
            • @ComponentScan(basePackages = "com.lirui.car")
              • 作用:告诉 Spring 扫描 com.lirui.car 包及其子包中的所有类,并自动将这些类注册为 Spring Bean。
              • 解释:任何标注了 @Component@Service@Repository@Controller 等注解的类都会被 Spring 容器管理。通过此注解,Spring 会自动扫描并注册这些类。
            • @PropertySource("classpath:application.properties")
              • 作用:指定一个外部的属性文件,在这个例子中是 application.properties,用于加载应用的配置。
              • 解释:通过 @PropertySource 注解,Spring 会读取 application.properties 文件中的内容,并将其中的配置值注入到 Spring 容器中的 Bean 类。
          • Car.java(汽车类)
              • @Component

                • 作用:标识 Car 类是一个 Spring 管理的组件(Bean)。
                • 解释:Spring 容器会自动扫描并将标注了 @Component 注解的类注册为 Bean。可以通过 @Autowired 注解来注入其他 Bean。
              • @Autowired

                • 作用:自动注入依赖。Spring 会根据类型自动查找并注入匹配的 Bean。
                • 解释:在构造函数上标注 @Autowired,Spring 会自动将 Engine 类型的 Bean 注入到 Car 类的 engine 属性中。
              • drive()

                • 作用:此方法用于打印 Car 类使用的引擎类型和马力。
                • 解释:通过 engine.getType()engine.getHorsepower() 获取并输出引擎类型和马力。
          • Engine.java(引擎类)
              • @Component

                • 作用:标识 Engine 类是一个 Spring 管理的 Bean。
                • 解释:Spring 容器会自动扫描并注册该类为一个 Bean,以便可以注入到其他组件中。
              • @Value("${car.engine.type}")@Value("${car.engine.horsepower}")

                • 作用:通过 @Value 注解将外部配置文件中的属性值注入到类的字段中。
                • 解释@Value 注解用来注入配置文件中的值。在这个例子中,car.engine.typecar.engine.horsepower 分别来自 application.properties 配置文件中的值。
              • 构造函数

                • 作用Engine 类的构造函数接收两个参数(typehorsepower),并将它们初始化到对应的实例变量中。
          • Main.java(主程序)
              • ApplicationContext

                • 作用ApplicationContext 是 Spring 的核心接口,提供了 Bean 管理和依赖注入等功能。
                • 解释:使用 AnnotationConfigApplicationContext 创建 Spring 容器,加载 AppConfig 配置类并初始化相关 Bean。
              • context.getBean(Car.class)

                • 作用:从 Spring 容器中获取 Car 类的实例。
                • 解释:通过 getBean() 方法从容器中获取已经定义的 Car Bean。Spring 会根据类类型来返回匹配的 Bean 实例。
              • car.drive()

                • 作用:调用 Car 类中的 drive() 方法,输出关于汽车和引擎的信息。
                • 解释:通过 Car 对象,调用 drive() 方法,最终打印出汽车的引擎类型和马力。
          • application.properties(配置文件)
              • car.engine.type=V8car.engine.horsepower=200
              • 作用:定义 car.engine.typecar.engine.horsepower 的配置项。
              • 解释:这些配置项会被加载到 Spring 环境中,并通过 @Value 注解注入到 Engine 类的 typehorsepower 字段中。
          • 注解总结:
            • @Configuration:用来标识配置类,替代传统的 XML 配置。
            • @ComponentScan:用来指定 Spring 容器扫描的包,自动注册符合条件的组件为 Bean。
            • @PropertySource:加载外部配置文件,注入其中的属性值。
            • @Component:标识一个类为 Spring 管理的 Bean。
            • @Autowired:自动注入依赖的 Bean。
            • @Value:将外部配置文件中的属性值注入到 Bean 的字段中。
      • Setter 注入:通过 Setter 方法将依赖注入到对象中。
        • Setter 注入的基本原理
          • Setter 注入依赖项的方式是通过 Spring 容器为 Bean 自动调用带有 @Autowired 注解的 Setter 方法来注入依赖对象。这种方式相比构造器注入更灵活,因为它允许在对象创建后进行依赖注入,而且依赖项也可以在 Bean 生命周期的不同阶段进行注入。
        • Setter 注入的优缺点
          • 优点:

            • 灵活性高:你可以选择是否为对象提供所有依赖,因为某些依赖项是通过 Setter 方法来注入的,可以选择不注入某些依赖,允许在不影响整个对象创建的情况下部分注入。

            • 更容易管理可选依赖:如果依赖项是可选的,Setter 注入允许不必在构造函数中强制要求所有依赖项都传入。

            • 避免构造函数过多:如果类的构造函数依赖项非常多,使用 Setter 注入可以避免构造函数的过度拥挤,使得类的接口保持简洁。

          • 缺点:

            • 不够安全:与构造器注入相比,Setter 注入依赖项是可选的,这可能导致对象在使用时缺少必需的依赖,造成运行时错误。

            • 依赖关系不明确:通过构造器注入,类的依赖项是不可变的,一目了然。而通过 Setter 注入,依赖关系在对象创建后才被设置,依赖的明确性较低。

            • 不支持必须的依赖项:Setter 注入无法保证在对象创建后依赖项已经完全注入,这可能导致空指针异常或不一致的状态。

        • Spring 容器工作原理
          • Spring 会在 Car 类的 Setter 方法上查找 @Autowired 注解,并将对应的依赖项注入进来(例如 EngineGPSRadio)。
          • 依赖项可以通过 Spring 容器中的配置自动提供,或者通过 XML 配置类手动声明并注入。
        • 案例实现:
          • // Engine.java
            public class Engine {
                private String type;
            
                public Engine(String type) {
                    this.type = type;
                }
            
                public String getType() {
                    return type;
                }
            }
            
            // GPS.java
            public interface GPS {
                void navigate();
            }
            
            // GPSImpl.java
            public class GPSImpl implements GPS {
                @Override
                public void navigate() {
                    System.out.println("正在用gps导航");
                }
            }
            
            // Radio.java
            public interface Radio {
                void playMusic();
            }
            
            // RadioImpl.java
            public class RadioImpl implements Radio {
                @Override
                public void playMusic() {
                   System.out.println("正在听音乐广播");
                }
            }
            
            package com.lirui.car;
            
            
            import org.springframework.beans.factory.annotation.Autowired;
            
            
            public class Car {
                private Engine engine;
                private GPS gps;
                private Radio radio;
            
                // Setter 注入方式
                @Autowired
                public void setEngine(Engine engine) {
                    this.engine = engine;
                }
            
                @Autowired
                public void setGps(GPS gps) {
                    this.gps = gps;
                }
            
                @Autowired
                public void setRadio(Radio radio) {
                    this.radio = radio;
                }
            
                public void drive() {
                    System.out.println("引擎"+engine.getType() );
                    gps.navigate();
                    radio.playMusic();
                }
            }
            
          • Spring 配置文件(基于 XML)
            • <?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">
              
                  <!--    applicationContext.xml 是 Spring 框架中的配置文件,
                  通常用于定义 Spring IoC(控制反转)容器中的 Bean 配置和管理。
                  这个文件主要用于将 Spring 的配置项和组件描述清楚,
                  告知 Spring 容器如何实例化、配置和管理应用程序中的各种对象(Bean)。
                  它是 Spring 配置的传统方式之一(除了注解和 Java 配置类)。-->
                  <!-- 定义 UserRepository Bean -->
                  <bean id="userRepository" class="com.lirui.example.UserRepository"/>
              
                  <!-- 定义 UserService Bean,注入 userRepository -->
                  <bean id="userService" class="com.lirui.example.UserService">
                      <constructor-arg ref="userRepository"/>
                  </bean>
              
                  <bean id="engine" class="com.lirui.car.Engine">
                      <constructor-arg value="V8"/>
                  </bean>
              
                  <bean id="gps" class="com.lirui.car.GPSImpl"/>
                  <bean id="radio" class="com.lirui.car.RadioImpl"/>
              
                  <bean id="car" class="com.lirui.car.Car">
                      <property name="engine" ref="engine"/>
                      <property name="gps" ref="gps"/>
                      <property name="radio" ref="radio"/>
                  </bean>
              
              
              <!--    <bean id="V8en" class="com.lirui.car.Engine">-->
              <!--        <constructor-arg value="V8"/>-->
              <!--        <constructor-arg value="500"/>-->
              <!--    </bean>-->
              
              <!--    <bean id="V6en" class="com.lirui.car.Engine">-->
              <!--        <constructor-arg value="V6"/>-->
              <!--        <constructor-arg value="200"/>-->
              <!--    </bean>-->
              
              <!--    <bean id="ca" class="com.lirui.car.Car">-->
              <!--        <constructor-arg ref="V6en"/>-->
              <!--    </bean>-->
              
              </beans>
              
          • 主程序

            • package com.lirui.car;
              
              import com.lirui.example.UserService;
              import org.springframework.context.ApplicationContext;
              import org.springframework.context.annotation.AnnotationConfigApplicationContext;
              import org.springframework.context.support.ClassPathXmlApplicationContext;
              
              public class Main {
              
                  public static void main(String[] args) {
                      // 加载 Spring 配置文件
                      ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
              
                      // 获取 userService Bean
                      Car car = context.getBean("car", Car.class);
              
                      // 调用方法
                      car.drive();
                  }
              }
              
          • 使用 Java 配置类
            • package com.lirui.car;
              
              
              import org.springframework.context.annotation.Bean;
              import org.springframework.context.annotation.ComponentScan;
              import org.springframework.context.annotation.Configuration;
              import org.springframework.context.annotation.PropertySource;
              
              @Configuration
              @ComponentScan(basePackages = "com.lirui.car")
              public class AppConfig {
              
                  @Bean
                  public Engine engine() {
                      return new Engine("V8");
                  }
              
                  @Bean
                  public GPS gps() {
                      return new GPSImpl();
                  }
              
                  @Bean
                  public Radio radio() {
                      return new RadioImpl();
                  }
              
                  @Bean
                  public Car car() {
                      Car car = new Car();
                      car.setEngine(engine());
                      car.setGps(gps());
                      car.setRadio(radio());
                      return car;
                  }
              }
          • 主程序

            • package com.lirui.car;
              
              import com.lirui.example.UserService;
              import org.springframework.context.ApplicationContext;
              import org.springframework.context.annotation.AnnotationConfigApplicationContext;
              import org.springframework.context.support.ClassPathXmlApplicationContext;
              
              public class Main {
              
                  public static void main(String[] args) {
                      // 使用 Java 配置类来初始化 Spring 容器
                      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
              
                      // 获取 Car 实例,依赖项会自动注入
                      Car car = context.getBean(Car.class);
                      car.drive();
              
                      context.close();
                  }
              }
              

      • 接口注入:这种方式不常见,是通过接口方法将依赖注入,一般不推荐。
    • Spring Bean 的生命周期

      • ​​​​实例化:容器通过反射实例化 Bean。

      • 属性注入:依赖关系被注入到 Bean 中。

      • 初始化:调用 @PostConstruct 方法,或者调用自定义的初始化方法(可以通过 init-method 属性指定)。

      • 使用:Bean 可以被应用程序使用。

      • 销毁:容器关闭时,Bean 会被销毁,调用 @PreDestroy 方法,或调用自定义的销毁方法(可以通过 destroy-method 属性指定)。

  • Spring Bean 的配置

    • 基于 XML 的配置

      • XML 配置是最早期的 Spring 配置方式,对项目结构有完整掌控的需求。

      • XML 配置文件的基础结构
        • <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 配置 -->
          </beans>
          

        • xmlnsxsi:schemaLocation 是定义 XML 命名空间和 XML Schema 的标准写法,用于使 Spring 能够理解配置文件。

        • beans 元素是 Spring 配置文件的根元素,所有 Bean 的配置都包含在 <beans> 元素中。

      • 定义 Bean
        • 每个 Spring Bean 都需要在 XML 配置文件中声明。使用 <bean> 元素来定义一个 Bean,id 属性用于指定 Bean 的名称,class 属性指定 Bean 的类。

        • 基本的 Bean 配置
          • <bean id="engine" class="com.lirui.car.Engine">
                <!-- 通过构造器传递参数 -->
                <constructor-arg value="V8"/>
            </bean>
          • id 属性指定了 Bean 的标识符,在容器中唯一。

          • class 属性指定了 Bean 对应的 Java 类。

        • Bean 的作用域
          • Spring Bean 的作用域(scope)决定了 Bean 实例的生命周期和它在容器中的共享方式。常用的作用域包括:

            • Singleton(默认作用域):Spring 容器中默认是单例模式,容器创建一个 Bean 实例,所有引用该 Bean 的地方都使用这个单例实例。

            • Prototype:每次请求时都会创建一个新的 Bean 实例。

            • Request:仅在 web 应用中有效,表示每个 HTTP 请求都会生成一个新的 Bean 实例。

            • Session:仅在 web 应用中有效,表示每个 HTTP 会话(Session)都会生成一个新的 Bean 实例。

          • <bean id="car" class="com.lirui.car.Car" scope="prototype">
                <constructor-arg ref="engine"/>
            </bean>
            

        • ​​​​​​​注入依赖
          •  构造器注入
            • ​​​​​​​​​​​​​​构造器注入是通过 <constructor-arg> 元素来为 Bean 的构造函数传递参数。如果 Bean 有多个构造函数,可以通过 indexname 属性来指定使用哪个构造函数。

            • value 用于传递简单类型的值(如字符串、数字等)。

            • ref 用于注入其他 Bean。

          •  属性注入(Setter 注入)
            • ​​​​​​​属性注入是通过 <property> 元素为 Bean 的属性注入值或引用其他 Bean。

            • name 属性指定目标属性的名称。

            • ref 属性指定要注入的其他 Bean。

            • <bean id="car" class="com.lirui.car.Car">
                  <property name="features">
                      <map>
                          <entry key="engine" value-ref="engine"/>
                          <entry key="gps" value-ref="gps"/>
                      </map>
                  </property>
              </bean>
          • ​​​​​​​集合注入
            • 注入一个集合类型(如 List、Set、Map、Properties 等),Spring 提供了对集合类型的支持。

            • <bean id="car" class="com.lirui.car.Car">
                  <property name="features">
                      <list>
                          <value>GPS</value>
                          <value>Radio</value>
                      </list>
                  </property>
              </bean>
          • ​​​​​​​​​​​​​​注入 Map
            • <bean id="car" class="com.lirui.car.Car">
                  <property name="features">
                      <map>
                          <entry key="engine" value-ref="engine"/>
                          <entry key="gps" value-ref="gps"/>
                      </map>
                  </property>
              </bean>
              
          • 注入 Properties
            • <bean id="car" class="com.lirui.car.Car">
                  <property name="properties">
                      <props>
                          <prop key="color">red</prop>
                          <prop key="type">sedan</prop>
                      </props>
                  </property>
              </bean>

        • 自动装配(Autowiring)
          • 自动装配允许 Spring 自动为 Bean 注入依赖,Spring 提供了几种自动装配的方式:autowire="byName"autowire="byType"autowire="constructor"

          • byName 根据 Bean 名称来进行自动装配

          • byType 根据 Bean 的类型来进行自动装配

          • 构造器自动装配 根据构造器参数的类型来自动装配相应的 Bean。

        • ​​​​​​​​​​​​​​加载 Bean 配置文件
          • Spring 提供了两种方式来加载 XML 配置文件:通过 ClassPathXmlApplicationContextFileSystemXmlApplicationContext

          • ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
            Car car = (Car) context.getBean("car");
            car.drive();
            ApplicationContext context = new FileSystemXmlApplicationContext("path/to/beans.xml");
            Car car = (Car) context.getBean("car");
            car.drive();
    • 基于注解的配置(@Component、@Service、@Repository、@Controller)

      • ​​​​​​​​​​​​​​注解配置在代码中直接标注 Bean 的定义,使得配置更加简洁和集中,常用的注解包括 @Component@Service@Repository@Controller 等。

      • 在 XML 中启用注解扫描:

        • <context:component-scan base-package="com.example" />
          
    • 基于 Java 配置类的配置

      • ​​​​​​​java 配置类基于 @Configuration@Bean 注解,可以完全替代 XML,提供更强的类型检查和代码提示。
      • import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;
        
        @Configuration
        public class AppConfig {
        
            @Bean
            public UserRepository userRepository() {
                return new UserRepository();
            }
        
            @Bean
            public UserService userService() {
                return new UserService(userRepository());
            }
        }
        
  • Spring AOP(面向切面编程)

    • AOP 概念与用途

      • ​​​​​​​​​​​​​​AOP 的核心是切面(Aspect),通过定义切面,可以在应用的各个切入点(Join Point)执行特定的行为。常见的横切关注点包括:

        • 日志记录:可以在方法执行前后记录日志。

        • 事务管理:确保在方法执行期间的数据库操作符合 ACID 特性。

        • 权限检查:在方法执行前检查用户权限。

    • AOP 切入点和通知类型(前置通知、后置通知、环绕通知等)

      • ​​​​​​​​​​​​​​在 Spring AOP 中,通知(Advice)是指在指定时间执行的动作。主要有以下几种类型:

        • 前置通知(@Before):在目标方法执行前执行。

        • 后置通知(@After):在目标方法执行后执行。

        • 返回通知(@AfterReturning):在目标方法正常返回后执行。

        • 异常通知(@AfterThrowing):在目标方法抛出异常后执行。

        • 环绕通知(@Around):可以在目标方法执行前后进行操作。

    • 使用 @Aspect 注解配置 AOP

      • ​​​​​​​开切
      • pom.xml
        • <?xml version="1.0" encoding="UTF-8"?>
          <project xmlns="http://maven.apache.org/POM/4.0.0"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
              <modelVersion>4.0.0</modelVersion>
          
              <groupId>com.lirui</groupId>
              <artifactId>demo05</artifactId>
              <version>1.0-SNAPSHOT</version>
          
              <properties>
                  <maven.compiler.source>8</maven.compiler.source>
                  <maven.compiler.target>8</maven.compiler.target>
                  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
              </properties>
              <dependencies>
                  <!-- Spring Context -->
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-context</artifactId>
                      <version>5.3.10</version>
                  </dependency>
          
           <!-- Spring aop -->
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-aop</artifactId>
                      <version>5.3.10</version>
                  </dependency>
           <!-- Spring aop -->
                  <dependency>
                      <groupId>org.aspectj</groupId>
                      <artifactId>aspectjrt</artifactId>
                      <version>1.9.8</version>
                  </dependency>
           <!-- Spring aop -->
                  <dependency>
                      <groupId>org.aspectj</groupId>
                      <artifactId>aspectjweaver</artifactId>
                      <version>1.9.8</version>
                  </dependency>
          
          
                  <!-- Spring Beans -->
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-beans</artifactId>
                      <version>5.3.10</version>
                  </dependency>
          
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-context</artifactId>
                      <version>5.3.10</version>
                  </dependency>
              </dependencies>
          
          </project>
          package com.lirui.car;
          
          
          import org.aspectj.lang.JoinPoint;
          import org.aspectj.lang.annotation.After;
          import org.aspectj.lang.annotation.Aspect;
          import org.aspectj.lang.annotation.Before;
          import org.springframework.stereotype.Component;
          
          @Aspect
          @Component
          public class CarAspect {
          
              // 在 Car 类的 drive 方法执行之前执行此方法
              @Before("execution(void com.lirui.car.Car.drive())")
              public void logBefore(JoinPoint joinPoint) {
                  System.out.println("Car drive() 方法执行之前的日志");
              }
          
              // 在 Car 类的 drive 方法执行之后执行此方法
              @After("execution(void com.lirui.car.Car.drive())")
              public void logAfter(JoinPoint joinPoint) {
                  System.out.println("Car drive() 方法执行之后的日志");
              }
          }
          

        • 配置类(XML 配置)

        • 配置类(Java 配置)

          • @EnableAspectJAutoProxy // 启用 AOP 支持

      • 还能自定义注解 然后实现日志操作  后边再说吧


http://www.kler.cn/a/382671.html

相关文章:

  • 查看 linux ubuntu 分区 和 挂载 情况 lsblk
  • 数据结构 - 图
  • 猎板PCB2到10层数的科技进阶与应用解析
  • Android——动态注册广播
  • 【Linux系列】利用 CURL 发送 POST 请求
  • 处理配对和拆分内容 |【python技能树知识点1~2 习题分析】
  • VS 中使用c#高版本语言方法
  • fs 中 rmSync 作用
  • 石墨舟氮气柜:半导体制造中的关键保护设备
  • 责任链模式 Chain of Responsibility
  • 【力扣打卡系列】单调栈
  • 熊猫追剧 1.0.0 | 免费追剧软件,全网资源,独家蓝光。
  • 传智杯 第六届-复赛-第二场-C
  • Vue全栈开发旅游网项目(8)-接口联调*2+用户登录
  • AI大模型如何重塑软件开发流程?
  • 工商业储能是什么,工商业储能有什么作用?
  • 作为一个前端开发者 以什么步骤学习后端技术
  • electron 设置最小窗口缩放
  • Java | Leetcode Java题解之第542题01矩阵
  • 高频面试题(含笔试高频算法整理)基本总结回顾32
  • RxJava最全面试题及参考答案
  • Linux qt下是使用搜狗輸入發
  • 全网最适合入门的面向对象编程教程:58 Python字符串与序列化-序列化Web对象的定义与实现
  • Android中Activity启动的模式
  • 算法——双指针
  • macOS15.1及以上系统bug:开发者证书无法打开,钥匙串访问无法打开一直出现图标后立马闪退