十二: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>
标签可以通过value
和ref
属性来传递构造函数的参数。它们的作用如下:-
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 会自动扫描并注册这些类。
- 作用:告诉 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.type
和car.engine.horsepower
分别来自application.properties
配置文件中的值。
- 作用:通过
-
构造函数:
- 作用:
Engine
类的构造函数接收两个参数(type
和horsepower
),并将它们初始化到对应的实例变量中。
- 作用:
-
-
Main.java
(主程序)-
-
ApplicationContext
:- 作用:
ApplicationContext
是 Spring 的核心接口,提供了 Bean 管理和依赖注入等功能。 - 解释:使用
AnnotationConfigApplicationContext
创建 Spring 容器,加载AppConfig
配置类并初始化相关 Bean。
- 作用:
-
context.getBean(Car.class)
:- 作用:从 Spring 容器中获取
Car
类的实例。 - 解释:通过
getBean()
方法从容器中获取已经定义的Car
Bean。Spring 会根据类类型来返回匹配的 Bean 实例。
- 作用:从 Spring 容器中获取
-
car.drive()
:- 作用:调用
Car
类中的drive()
方法,输出关于汽车和引擎的信息。 - 解释:通过
Car
对象,调用drive()
方法,最终打印出汽车的引擎类型和马力。
- 作用:调用
-
-
application.properties
(配置文件)-
car.engine.type=V8
和car.engine.horsepower=200
:- 作用:定义
car.engine.type
和car.engine.horsepower
的配置项。 - 解释:这些配置项会被加载到 Spring 环境中,并通过
@Value
注解注入到Engine
类的type
和horsepower
字段中。
-
- 注解总结:
@Configuration
:用来标识配置类,替代传统的 XML 配置。@ComponentScan
:用来指定 Spring 容器扫描的包,自动注册符合条件的组件为 Bean。@PropertySource
:加载外部配置文件,注入其中的属性值。@Component
:标识一个类为 Spring 管理的 Bean。@Autowired
:自动注入依赖的 Bean。@Value
:将外部配置文件中的属性值注入到 Bean 的字段中。
- 在 Spring 3.0 及以后的版本中,可以通过
-
-
Setter 注入:通过
Setter
方法将依赖注入到对象中。-
Setter 注入的基本原理
- Setter 注入依赖项的方式是通过 Spring 容器为 Bean 自动调用带有
@Autowired
注解的 Setter 方法来注入依赖对象。这种方式相比构造器注入更灵活,因为它允许在对象创建后进行依赖注入,而且依赖项也可以在 Bean 生命周期的不同阶段进行注入。
- Setter 注入依赖项的方式是通过 Spring 容器为 Bean 自动调用带有
-
Setter 注入的优缺点
-
优点:
-
灵活性高:你可以选择是否为对象提供所有依赖,因为某些依赖项是通过 Setter 方法来注入的,可以选择不注入某些依赖,允许在不影响整个对象创建的情况下部分注入。
-
更容易管理可选依赖:如果依赖项是可选的,Setter 注入允许不必在构造函数中强制要求所有依赖项都传入。
-
避免构造函数过多:如果类的构造函数依赖项非常多,使用 Setter 注入可以避免构造函数的过度拥挤,使得类的接口保持简洁。
-
-
缺点:
-
不够安全:与构造器注入相比,Setter 注入依赖项是可选的,这可能导致对象在使用时缺少必需的依赖,造成运行时错误。
-
依赖关系不明确:通过构造器注入,类的依赖项是不可变的,一目了然。而通过 Setter 注入,依赖关系在对象创建后才被设置,依赖的明确性较低。
-
不支持必须的依赖项:Setter 注入无法保证在对象创建后依赖项已经完全注入,这可能导致空指针异常或不一致的状态。
-
-
-
Spring 容器工作原理
- Spring 会在
Car
类的 Setter 方法上查找@Autowired
注解,并将对应的依赖项注入进来(例如Engine
、GPS
、Radio
)。 - 依赖项可以通过 Spring 容器中的配置自动提供,或者通过 XML 配置类手动声明并注入。
- Spring 会在
-
案例实现:
-
// 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>
-
xmlns
和xsi: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 有多个构造函数,可以通过index
或name
属性来指定使用哪个构造函数。 -
-
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 配置文件:通过
ClassPathXmlApplicationContext
和FileSystemXmlApplicationContext
。 -
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()); } }
- java 配置类基于
-
-
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 支持
-
-
还能自定义注解 然后实现日志操作 后边再说吧
-