当前位置: 首页 > 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 支持

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

相关文章:

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

目录 创建项目 Spring 核心基础 Spring 容器 Spring 容器的作用 Spring 容器的工作流程 Bean Bean 的生命周期 IOC&#xff08;控制反转&#xff09;与依赖注入&#xff08;DI&#xff09; 控制反转的概念 依赖注入的几种方式&#xff08;构造器注入、Setter 注入、接…...

new和malloc有什么区别,他们的用法是什么?malloc分配失败会导致什么问题

1) new和malloc的区别&#xff0c;和他们的用法 new 和 malloc 主要有以下区别&#xff1a; 一、性质和来源 new &#xff1a;是 C 的运算符&#xff0c;在操作时会调用构造函数进行对象的初始化。它是 C 语言层面的操作&#xff0c;能更好地与 C 的面向对象特性结合。 malloc …...

了解SQLExpress数据库

SQLExpress&#xff08;Microsoft SQL Server Express&#xff09;是由微软公司开发的一款免费且轻量级的数据库管理系统。以下是关于SQLExpress的详细解释&#xff1a; 一、定义与特点 定义&#xff1a; SQLExpress是Microsoft SQL Server的一个缩减版或基础版&#xff0c;旨在…...

geoserver创建一个根据属性显示不同形状的点样式

geoserver创建一个根据属性显示不同形状的点样式 三角形 -triangle 圆形 - circle 正方形 - square 星形 - star 十字形 - cross 菱形 -diamond 代码&#xff1a; <?xml version"1.0" encoding"UTF-8"?> <StyledLayerDescriptor version"…...

中国遗传学会2024全国学术研讨会在长沙成功召开

2024年11月3日至6日&#xff0c;备受瞩目的中国遗传学会2024全国学术研讨会在长沙盛大召开&#xff0c;此次盛会由中国遗传学会携手湖南省遗传学会共同主办&#xff0c;中南大学与南华大学共同承办。大会以“遗传学&#xff1a;前沿与交叉”为主题&#xff0c;吸引了来自全国各…...

Android Studio 多工程公用module引用

在Android Studio中&#xff0c;如果有多个工程需要共享同一个module&#xff0c;你可以通过以下步骤来实现module的公用&#xff1a; 1.将你想共享的module移动到一个单独的目录&#xff0c;比如一个新建的"libraries"文件夹。 2.修改module的build.gradle文件&am…...

(实战)WebApi第9讲:EFCore性能优化(IQueryable延迟查询、取消跟踪机制)

一、例子是第8讲的四、6&#xff08;EFCore的静态化处理 &#xff09;&#xff1a;分析ToList() ToList()在下图绿色框内。 二、在没有最终取数据的时候&#xff0c;使用 IQueryable<T> 延迟执行查询 &#xff08;1&#xff09;在没有最终取数据的时候&#xff0c;不要使…...

Java实现pdf转图片

第一步 <dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.32</version> <!-- 请检查最新版本 --> </dependency> 第二步 package com.example.demo.file.pdf;import or…...

健身房管理新纪元:SpringBoot技术应用

4系统概要设计 4.1概述 本系统采用B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式&#xff0c;是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示&#xff1a; 图4-1系统工作原理…...

Java之字符串分割转换List

Java之字符串分割转换List 字符串分割成数组然后转换成List有多种方式&#xff0c;以下是每种方式的示例&#xff0c;推荐Java8的新特性Stream。 使用Java8的新特性Stream API String str "aaa,bbb,ccc"; // 使用Arrays.stream() List<String> list1 …...

RabbitMQ如何保证发送的消息可靠(RabbitMQ的Confirm模式和2.Return模式)

RabbitMQ如何保证发送的消息可靠&#xff08;RabbitMQ的Confirm模式和2.Return模式&#xff09; 1、RabbitMQ消息Confirm模式&#xff08;保证从生产者到交换机的消息可靠&#xff09;1.1、Confirm模式简介1.2、具体代码实现1.2.1、application.yml 开启确认模式1.2.2、生产者方…...

适配器模式:类适配器与对象适配器

适配器模式是一种结构性设计模式&#xff0c;旨在将一个接口转换成客户端所期望的另一种接口。它通常用于解决由于接口不兼容而导致的类之间的通信问题。适配器模式主要有两种实现方式&#xff1a;类适配器和对象适配器。下面&#xff0c;我们将详细探讨这两种方式的优缺点及适…...

volatile原理

volatile原理 volatile的底层实现原理是内存屏障,Memory Barrier(Memory Fence) 对volatile变量的写指令后会加入写屏障 对volatile变量的读指令前会加入读屏障 如何保证可见性 写屏障保证在该屏障之前的,对共享变量的改动,都同步到主存当中 public void actor2(I_Resu…...

【AI神器】SD(Stable Diffusion)一键安装包

是否还在无法使用Stable Diffusion 而烦恼&#xff0c;今天就给大家带来sd的私有化部署&#xff0c;一键安装包 https://pan.quark.cn/s/c16aa752ac6a 当然对电脑配置略微有些要求&#xff1a; 首先&#xff0c;本地安装对电脑配置有一些基本要求&#xff0c; 本地电脑安装…...

lanqiaoOJ 1112:小王子双链表 ← STL list

【题目来源】https://www.lanqiao.cn/problems/1112/learning/【题目描述】 小王子有一天迷上了排队的游戏&#xff0c;桌子上有标号为 1-10 的 10 个玩具&#xff0c;现在小王子将他们排成一列&#xff0c;可小王子还是太小了&#xff0c;他不确定他到底想把那个玩具摆在哪里&…...

C#WPF之快速理解MVVM模式

MVVM是一种设计模式&#xff0c;特别适用于WPF等XAML-based的应用程序开发。MVVM模式主要包含三个部分&#xff1a;Model&#xff08;模型&#xff09;、View&#xff08;视图&#xff09;和ViewModel&#xff08;视图模型&#xff09;。 Model&#xff08;模型&#xff09;&a…...

微积分[1]|微积分的底层逻辑——解析几何、不等式与极限(含博主推荐的数理阅读教材共计21本书籍)

原创首发于CSDN&#xff0c;禁止转载&#xff0c;谢谢&#xff01; 文章目录 微积分的底层逻辑探究一篇网络文章《数学分析的核心——不等式》高中数学与大学数学的脱节&#xff5c;脱节的实质含义&#xff5c;高中与大学的衔接数理书籍推荐 我个人所认为的数学分析的根基更新时…...

1-磁盘建立空闲分区

学习目标&#xff1a; 掌握磁盘分区的基本知识和操作技能&#xff0c;能够独立创建和管理磁盘空闲分区&#xff0c;以优化存储空间和提高系统性能&#xff0c;为后续的系统安装和数据管理打下基础。 学习内容&#xff1a; 1 选择一个适合的磁盘分区软件。推荐DiskGenius、Par…...

使用SearXNG-搭建个人搜索引擎(附国内可用Docker镜像源)

介绍 SearXNG是聚合了七十多种搜索服务的开源搜索工具。我们可以匿名浏览页面&#xff0c;不会被记录和追踪。作为开发者&#xff0c;SearXNG也提供了清晰的API接口以及完整的开发文档。 部署 我们可以很方便地使用Docker和Docker compose部署SearXNG。下面给出Docker部署Se…...

InnoDB 存储引擎<五>undo log, redo log,以及双写缓冲区

目录 撤销⽇志 - Undo Log 双写缓冲区 - Doublewrite Buffer 重做⽇志 - Redo Log 本篇是继承自上篇InnoDB存储引擎的磁盘文件 上篇链接&#xff1a;InnoDB 存储引擎&#xff1c;四&#xff1e;磁盘文件一 撤销⽇志 - Undo Log 1.什么是撤销⽇志&#xff1f; 解答问题&a…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

Docker 本地安装 mysql 数据库

Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker &#xff1b;并安装。 基础操作不再赘述。 打开 macOS 终端&#xff0c;开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...