十二: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>
标签可以通过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/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 会自动扫描并注册这些类。
- 作用:告诉 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 {@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>
-
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 {@Beanpublic UserRepository userRepository() {return new UserRepository();}@Beanpublic 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 支持
-
-
-
-
还能自定义注解 然后实现日志操作 后边再说吧
-
相关文章:

十二:java web(4)-- Spring核心基础
目录 创建项目 Spring 核心基础 Spring 容器 Spring 容器的作用 Spring 容器的工作流程 Bean Bean 的生命周期 IOC(控制反转)与依赖注入(DI) 控制反转的概念 依赖注入的几种方式(构造器注入、Setter 注入、接…...
new和malloc有什么区别,他们的用法是什么?malloc分配失败会导致什么问题
1) new和malloc的区别,和他们的用法 new 和 malloc 主要有以下区别: 一、性质和来源 new :是 C 的运算符,在操作时会调用构造函数进行对象的初始化。它是 C 语言层面的操作,能更好地与 C 的面向对象特性结合。 malloc …...

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

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

中国遗传学会2024全国学术研讨会在长沙成功召开
2024年11月3日至6日,备受瞩目的中国遗传学会2024全国学术研讨会在长沙盛大召开,此次盛会由中国遗传学会携手湖南省遗传学会共同主办,中南大学与南华大学共同承办。大会以“遗传学:前沿与交叉”为主题,吸引了来自全国各…...
Android Studio 多工程公用module引用
在Android Studio中,如果有多个工程需要共享同一个module,你可以通过以下步骤来实现module的公用: 1.将你想共享的module移动到一个单独的目录,比如一个新建的"libraries"文件夹。 2.修改module的build.gradle文件&am…...

(实战)WebApi第9讲:EFCore性能优化(IQueryable延迟查询、取消跟踪机制)
一、例子是第8讲的四、6(EFCore的静态化处理 ):分析ToList() ToList()在下图绿色框内。 二、在没有最终取数据的时候,使用 IQueryable<T> 延迟执行查询 (1)在没有最终取数据的时候,不要使…...
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服务两种模式,是一个适用于Internet环境下的模型结构。只要用户能连上Internet,便可以在任何时间、任何地点使用。系统工作原理图如图4-1所示: 图4-1系统工作原理…...
Java之字符串分割转换List
Java之字符串分割转换List 字符串分割成数组然后转换成List有多种方式,以下是每种方式的示例,推荐Java8的新特性Stream。 使用Java8的新特性Stream API String str "aaa,bbb,ccc"; // 使用Arrays.stream() List<String> list1 …...

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

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

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

【AI神器】SD(Stable Diffusion)一键安装包
是否还在无法使用Stable Diffusion 而烦恼,今天就给大家带来sd的私有化部署,一键安装包 https://pan.quark.cn/s/c16aa752ac6a 当然对电脑配置略微有些要求: 首先,本地安装对电脑配置有一些基本要求, 本地电脑安装…...
lanqiaoOJ 1112:小王子双链表 ← STL list
【题目来源】https://www.lanqiao.cn/problems/1112/learning/【题目描述】 小王子有一天迷上了排队的游戏,桌子上有标号为 1-10 的 10 个玩具,现在小王子将他们排成一列,可小王子还是太小了,他不确定他到底想把那个玩具摆在哪里&…...

C#WPF之快速理解MVVM模式
MVVM是一种设计模式,特别适用于WPF等XAML-based的应用程序开发。MVVM模式主要包含三个部分:Model(模型)、View(视图)和ViewModel(视图模型)。 Model(模型)&a…...
微积分[1]|微积分的底层逻辑——解析几何、不等式与极限(含博主推荐的数理阅读教材共计21本书籍)
原创首发于CSDN,禁止转载,谢谢! 文章目录 微积分的底层逻辑探究一篇网络文章《数学分析的核心——不等式》高中数学与大学数学的脱节|脱节的实质含义|高中与大学的衔接数理书籍推荐 我个人所认为的数学分析的根基更新时…...

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

使用SearXNG-搭建个人搜索引擎(附国内可用Docker镜像源)
介绍 SearXNG是聚合了七十多种搜索服务的开源搜索工具。我们可以匿名浏览页面,不会被记录和追踪。作为开发者,SearXNG也提供了清晰的API接口以及完整的开发文档。 部署 我们可以很方便地使用Docker和Docker compose部署SearXNG。下面给出Docker部署Se…...

InnoDB 存储引擎<五>undo log, redo log,以及双写缓冲区
目录 撤销⽇志 - Undo Log 双写缓冲区 - Doublewrite Buffer 重做⽇志 - Redo Log 本篇是继承自上篇InnoDB存储引擎的磁盘文件 上篇链接:InnoDB 存储引擎<四>磁盘文件一 撤销⽇志 - Undo Log 1.什么是撤销⽇志? 解答问题&a…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

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

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

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

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...

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

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