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

十二: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 BeanUserService 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/beanshttp://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/beanshttp://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;@Autowiredpublic 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 {@Overridepublic void navigate() {System.out.println("正在用gps导航");}
            }// Radio.java
            public interface Radio {void playMusic();
            }// RadioImpl.java
            public class RadioImpl implements Radio {@Overridepublic 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 注入方式@Autowiredpublic void setEngine(Engine engine) {this.engine = engine;}@Autowiredpublic void setGps(GPS gps) {this.gps = gps;}@Autowiredpublic 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/beanshttp://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 BeanCar 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 {@Beanpublic Engine engine() {return new Engine("V8");}@Beanpublic GPS gps() {return new GPSImpl();}@Beanpublic Radio radio() {return new RadioImpl();}@Beanpublic 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/beanshttp://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 {@Beanpublic UserRepository userRepository() {return new UserRepository();}@Beanpublic 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.mrgr.cn/news/67369.html

相关文章:

  • 如何使用Netdata部署高性能的服务器监控平台
  • 鸿蒙5.0时代:原生鸿蒙应用市场引领开发者服务新篇章
  • LabVIEW编程过程中为什么会出现bug?
  • 15分钟学 Go 第 36 天:Go的反射基础
  • 云服务器防火墙设置方法
  • SQL中的IN语句和EXISTS语句
  • GPU释放威力:在Gymnasium环境中使用稳定基线3在AMD GPU上训练强化学习代理
  • 科比投篮预测的数据处理与分析
  • 网络初始:TCP/IP 五层协议模型 网络通信基本流程
  • 解释Python的排序方法sort和sorted的区别。
  • 详解Rust标准库:BTreeSet
  • 数字信号处理Python示例(7)生成复数指数函数
  • Python | Leetcode Python题解之第543题二叉树的直径
  • 提高区块链网络TPS七步曲
  • 【知识科普】使用 OpenSSL为特定域名生成自签名证书
  • Python 详细实现无损压缩之 DEFLATE 算法
  • VS2013安装报错“windows程序兼容性模式已打开,请将其关闭 ”解决方案
  • Python | Leetcode Python题解之第542题01矩阵
  • wps怎么算出一行1和0两种数值中连续数值1的个数,出现0后不再计算?
  • Python练习9
  • 快速部署和体验内置开源 LLM 大模型
  • UE5.4 PCG基础节点
  • 【Linux 29】传输层协议 - UDP
  • Linux 使用及常用命令详解
  • 【Linux-进程间通信】消息队列
  • LLMs之Leaderboard:Chatbot Arena的简介、使用方法、案例应用之详细攻略