一、Spring 核心总览(大白话)
Spring 干两件大事:
- IOC 容器:帮你创建对象、管理对象(Bean 生命周期)
- AOP 切面:不修改源码,给方法统一加功能(日志、事务、异常)
学习顺序:Bean 生命周期 → 作用域 → AOP 5 种增强 → execution 表达式
二、第一部分:Spring Bean 完整生命周期(从生到死)
1. 生命周期固定 12 步(必须背)
- 执行无参构造:创建对象
- 执行set 方法:属性赋值
- BeanNameAware:知道自己在 Spring 里的名字
- BeanFactoryAware:拿到父容器
- ApplicationContextAware:拿到 Spring 核心容器
- BeanPostProcessor 前置:初始化前处理
- InitializingBean:官方初始化
- 自定义 init-method:自己的初始化
- BeanPostProcessor 后置:初始化后修改
- Bean 正常使用
- DisposableBean:官方销毁
- 自定义 destroy-method:自己的销毁
2. 全套整合代码(生命周期 + 作用域)
2.1 生命周期 Bean(实现所有接口)
java
运行
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class UserBean implements
BeanNameAware,
BeanFactoryAware,
ApplicationContextAware,
InitializingBean,
DisposableBean {
private String id;
private String name;
private int age;
// 1 构造方法
public UserBean() {
System.out.println("【1 构造】对象创建");
}
// 2 set 赋值
public void setId(String id) {
this.id = id;
System.out.println("【2 set】id = " + id);
}
public void setName(String name) {
this.name = name;
System.out.println("【2 set】name = " + name);
}
public void setAge(int age) {
this.age = age;
System.out.println("【2 set】age = " + age);
}
// 3 BeanNameAware
@Override
public void setBeanName(String name) {
System.out.println("【3 Aware】我的名字:" + name);
}
// 4 BeanFactoryAware
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【4 Aware】父容器注入");
}
// 5 ApplicationContextAware
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("【5 Aware】Spring 核心容器注入");
}
// 7 接口初始化
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【7 初始化】接口初始化");
}
// 8 自定义初始化
public void myInit() {
System.out.println("【8 初始化】自定义初始化");
}
// 业务方法
public void show() {
System.out.println("【使用中】id=" + id + " name=" + name + " age=" + age);
}
// 11 接口销毁
@Override
public void destroy() throws Exception {
System.out.println("【11 销毁】接口销毁");
}
// 12 自定义销毁
public void myDestroy() {
System.out.println("【12 销毁】自定义销毁");
}
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
2.2 BeanPostProcessor 全局处理器
java
运行
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userBean".equals(beanName)) {
System.out.println("【6 前置】初始化前");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("userBean".equals(beanName)) {
System.out.println("【9 后置】初始化后,修改 age=99");
UserBean userBean = (UserBean) bean;
userBean.setAge(99);
}
return bean;
}
}
2.3 作用域测试 Bean
java
运行
public class ScopeBean {
public ScopeBean() {
System.out.println("【作用域】ScopeBean 构造");
}
}
三、第二部分:AOP 全套 5 种增强(整合版)
包含:前置、后置、异常、环绕、最终全覆盖!
3.1 目标业务类
java
运行
public class UserService {
public void login(String username) {
System.out.println("【业务】用户 " + username + " 登录成功");
}
public void pay() {
System.out.println("【业务】执行支付");
throw new RuntimeException("支付失败,余额不足");
}
}
3.2 AOP 全套增强类(5 种增强写在一起)
java
运行
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AllAdvice {
// 前置
public void before() {
System.out.println("【前置】开启事务");
}
// 后置
public void afterReturning() {
System.out.println("【后置】提交事务");
}
// 异常
public void afterThrowing() {
System.out.println("【异常】回滚事务");
}
// 环绕(最强大)
public Object around(MethodInvocation invocation) throws Throwable {
System.out.println("【环绕前】");
Object result = null;
try {
result = invocation.proceed();
} catch (Exception e) {
System.out.println("【环绕异常】");
throw e;
} finally {
System.out.println("【环绕后】");
}
return result;
}
// 最终
public void after() {
System.out.println("【最终】释放资源");
}
}
四、第三部分:Spring 核心配置文件(全套整合一个 XML)
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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- ==================== 1. 生命周期 Bean ==================== -->
<bean class="com.demo.MyProcessor"/>
<bean id="userBean" class="com.demo.UserBean"
init-method="myInit" destroy-method="myDestroy">
<property name="id" value="1001"/>
<property name="name" value="整合测试"/>
<property name="age" value="20"/>
</bean>
<!-- ==================== 2. 作用域 Bean ==================== -->
<bean id="scopeSingleton" class="com.demo.ScopeBean" scope="singleton"/>
<bean id="scopePrototype" class="com.demo.ScopeBean" scope="prototype"/>
<!-- ==================== 3. AOP 全套配置 ==================== -->
<bean id="userService" class="com.demo.UserService"/>
<bean id="allAdvice" class="com.demo.AllAdvice"/>
<aop:config>
<aop:pointcut id="allPoint" expression="execution(* com.demo.UserService.*(..))"/>
<aop:before method="before" pointcut-ref="allPoint"/>
<aop:after-returning method="afterReturning" pointcut-ref="allPoint"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="allPoint"/>
<aop:around method="around" pointcut-ref="allPoint"/>
<aop:after method="after" pointcut-ref="allPoint"/>
</aop:config>
</beans>
五、第四部分:最终整合测试类(一个主方法运行全部)
这就是你要的完整练习代码案例!
java
运行
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TotalTest {
public static void main(String[] args) {
System.out.println("=============== 1. 启动 Spring ===============");
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
System.out.println("\n=============== 2. 测试生命周期 ===============");
UserBean userBean = context.getBean("userBean", UserBean.class);
userBean.show();
System.out.println("\n=============== 3. 测试作用域 ===============");
ScopeBean s1 = context.getBean("scopeSingleton", ScopeBean.class);
ScopeBean s2 = context.getBean("scopeSingleton", ScopeBean.class);
System.out.println("单例是否同一个:" + (s1 == s2)); // true
ScopeBean s3 = context.getBean("scopePrototype", ScopeBean.class);
ScopeBean s4 = context.getBean("scopePrototype", ScopeBean.class);
System.out.println("多例是否同一个:" + (s3 == s4)); // false
System.out.println("\n=============== 4. 测试AOP全套增强 ===============");
UserService userService = context.getBean("userService", UserService.class);
// 正常方法
userService.login("整合测试用户");
System.out.println("------------------------------------");
// 异常方法
try {
userService.pay();
} catch (Exception e) {}
System.out.println("\n=============== 5. 关闭容器 ===============");
ClassPathXmlApplicationContext ctx = (ClassPathXmlApplicationContext) context;
ctx.close();
}
}
六、运行结果(全部内容一次性展示)
plaintext
=============== 1. 启动 Spring ===============
【1 构造】对象创建
【2 set】id = 1001
【2 set】name = 整合测试
【2 set】age = 20
【3 Aware】我的名字:userBean
【4 Aware】父容器注入
【5 Aware】Spring 核心容器注入
【6 前置】初始化前
【7 初始化】接口初始化
【8 初始化】自定义初始化
【9 后置】初始化后,修改 age=99
【作用域】ScopeBean 构造
=============== 2. 测试生命周期 ===============
【使用中】id=1001 name=整合测试 age=99
=============== 3. 测试作用域 ===============
单例是否同一个:true
【作用域】ScopeBean 构造
【作用域】ScopeBean 构造
多例是否同一个:false
=============== 4. 测试AOP全套增强 ===============
【前置】开启事务
【环绕前】
【业务】用户 整合测试用户 登录成功
【环绕后】
【后置】提交事务
【最终】释放资源
------------------------------------
【前置】开启事务
【环绕前】
【业务】执行支付
【环绕异常】
【异常】回滚事务
【最终】释放资源
=============== 5. 关闭容器 ===============
【11 销毁】接口销毁
【12 销毁】自定义销毁