Spring 核心知识点全解析(IOC+AOP)

前言

Spring 框架作为 Java EE 开发的中流砥柱,其核心思想(IOC 控制反转、AOP 面向切面编程)彻底解决了传统开发中代码耦合、功能复用性差等问题。本文将从 Spring 概述入手,逐步拆解 IOC 和 AOP 的实现原理、配置方式,结合实战案例让你彻底掌握 Spring 核心!

一、Spring 概述

1.1 Spring 是什么?

Spring 是轻量级 Java EE 应用开源框架(官网:http://spring.io/),由 Rod Johnson 为解决企业级编程开发的复杂性而创建。它并非替代现有框架,而是通过整合各类技术,为开发者提供一站式解决方案。

1.2 Spring 简化开发的核心体现

特性 作用
IOC(控制反转) 解决传统开发中硬编码导致的程序耦合问题
AOP(面向切面编程) 运行期间不修改源代码即可对程序功能增强
粘合剂特性 提供整合 MyBatis、Struts2 等其他框架的能力

1.3 Spring 体系结构

Spring 框架按功能划分为五大核心模块:

  • Core Container(核心容器):提供 IOC 和 DI(依赖注入)核心能力,包含 beans、core、context、expression 模块。
  • AOP + Aspects:面向切面编程实现,支持功能增强。
  • Data Access/Integration:简化持久层操作,整合 JDBC、ORM(MyBatis/Hibernate)等。
  • Web:提供 Spring MVC 框架,支持 Servlet、WebSocket 等 Web 开发。
  • Test:集成 JUnit、TestNG 等测试框架,简化单元测试。

1.4 Spring 发展历程

  • 1997 年:IBM 提出 EJB 思想;
  • 2002 年:Rod Johnson 发布《Expert One-to-One J2EE Design and Development》,阐述 EJB 开发痛点;
  • 2004 年:《Expert One-to-One J2EE Development without EJB》发布,奠定 Spring 雏形;
  • 2017 年:Spring 5.0 通用版发布,至今仍是主流版本。

二、Spring IOC(控制反转)- 核心重点

2.1 程序耦合的问题

传统开发中,Web 层、业务层、持久层存在强耦合,例如:

java 复制代码
// 持久层实现类
public class UserDaoImpl implements UserDao {
    @Override
    public void addUser(){
        System.out.println("insert into tb_user......");
    }
}

// 业务层实现类
public class UserServiceImpl implements UserService {
    // 硬编码依赖:直接new Dao层对象
    private UserDao userDao = new UserDaoImpl();
    public void addUser(){
        userDao.addUser();
    }
}

// 表现层
public class Client {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        userService.addUser();
    }
}

问题分析:若修改 Dao 层实现类,Service 层编译失败,耦合度极高。

2.2 IOC 核心思想:控制反转

  • 正传:开发者主动 new 对象(如上述代码),控制对象创建权;
  • 反转:由 IOC 工厂统一创建、管理对象,开发者被动获取,实现解耦。
2.2.1 工厂模式实现 IOC 解耦(手动实现)

步骤 1:编写配置文件(bean.properties)

java 复制代码
UserDao=com.hg.dao.UserDaoImpl
UserService=com.hg.service.UserServiceImpl

步骤 2:实现 IOC 工厂类

java 复制代码
public class BeanFactory {
    // 容器存储对象
    private static Map<String, Object> beans = new HashMap<>();
    
    // 静态代码块加载配置文件并创建对象
    static {
        try {
            InputStream is = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
            Properties prop = new Properties();
            prop.load(is);
            // 遍历配置文件,反射创建对象
            Set<Object> keys = prop.keySet();
            for (Object key : keys) {
                String beanName = (String) key;
                String className = prop.getProperty(beanName);
                Object bean = Class.forName(className).newInstance();
                beans.put(beanName, bean);
            }
        } catch (Exception e) {
            throw new ExceptionInInitializerError("初始化Bean工厂失败");
        }
    }
    
    // 获取对象方法
    public static Object getBean(String beanName) {
        return beans.get(beanName);
    }
}

步骤 3:改造 Service 层

java 复制代码
public class UserServiceImpl implements UserService {
    // 从工厂获取对象,而非手动new
    private UserDao userDao = (UserDao) BeanFactory.getBean("UserDao");
    public void addUser(){
        userDao.addUser();
    }
}

2.3 Spring 官方 IOC 实现

2.3.1 快速上手(XML 配置)

步骤 1:创建 Maven 工程,引入依赖

XML 复制代码
<dependencies>
    <!-- Spring核心依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.8.RELEASE</version>
    </dependency>
</dependencies>

步骤 2:编写 Spring 配置文件(applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 将对象交给Spring容器管理 -->
    <bean id="userDao" class="com.hg.dao.UserDaoImpl"></bean>
    <bean id="userService" class="com.hg.service.UserServiceImpl"></bean>
</beans>

步骤 3:测试获取容器对象

java 复制代码
public class Client {
    public static void main(String[] args) {
        // 加载配置文件,创建Spring容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 从容器获取对象
        UserDao userDao = (UserDao) ac.getBean("userDao");
        UserService userService = (UserService) ac.getBean("userService");
        userService.addUser();
    }
}
2.3.2 DI(依赖注入)- 解决 Service 层耦合

IOC 解决对象创建问题,DI 解决对象依赖赋值问题,核心有 4 种注入方式:

方式 1:构造函数注入
java 复制代码
// Service层
public class UserServiceImpl implements UserService {
    private UserDao userDao;
    private String name;
    private Integer age;
    
    // 构造方法
    public UserServiceImpl(UserDao userDao, String name, Integer age) {
        this.userDao = userDao;
        this.name = name;
        this.age = age;
    }
    
    @Override
    public void addUser(){
        System.out.println(name + "," + age);
        userDao.addUser();
    }
}
XML 复制代码
<!-- 配置文件 -->
<bean id="userDao" class="com.hg.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.hg.service.UserServiceImpl">
    <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    <constructor-arg name="name" value="张三"></constructor-arg>
    <constructor-arg name="age" value="18"></constructor-arg>
</bean>
方式 2:Set 方法注入(最常用)
java 复制代码
// Service层
public class UserServiceImpl implements UserService {
    private UserDao userDao;
    private String name;
    private Integer age;
    
    // Set方法
    public void setUserDao(UserDao userDao) {this.userDao = userDao;}
    public void setName(String name) {this.name = name;}
    public void setAge(Integer age) {this.age = age;}
    
    @Override
    public void addUser(){
        System.out.println(name + "," + age);
        userDao.addUser();
    }
}
XML 复制代码
<!-- 配置文件 -->
<bean id="userDao" class="com.hg.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.hg.service.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
    <property name="name" value="张三"></property>
    <property name="age" value="18"></property>
</bean>
方式 3:自动注入
XML 复制代码
<!-- byType:按类型注入;byName:按bean的id注入 -->
<bean id="userDao" class="com.hg.dao.UserDaoImpl"></bean>
<bean id="userService" class="com.hg.service.UserServiceImpl" autowire="byType"></bean>
方式 4:集合类型注入(了解)
java 复制代码
// Service层
public class UserServiceImpl implements UserService {
    private String[] myStrs;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,String> myMap;
    
    // Set方法省略...
    
    @Override
    public void addUser(){
        System.out.println(Arrays.toString(myStrs));
        System.out.println(myList);
        System.out.println(mySet);
        System.out.println(myMap);
    }
}
XML 复制代码
<!-- 配置文件 -->
<bean id="userService" class="com.hg.service.UserServiceImpl">
    <property name="myStrs">
        <array>
            <value>AAA</value>
            <value>BBB</value>
        </array>
    </property>
    <property name="myList">
        <list>
            <value>AAA</value>
            <value>BBB</value>
        </list>
    </property>
    <property name="mySet">
        <set>
            <value>AAA</value>
            <value>BBB</value>
        </set>
    </property>
    <property name="myMap">
        <map>
            <entry key="key1" value="value1"></entry>
            <entry key="key2" value="value2"></entry>
        </map>
    </property>
</bean>

未完待续~~~

相关推荐
absunique2 小时前
Spring boot 3.3.1 官方文档 中文
java·数据库·spring boot
召田最帅boy2 小时前
Spring Boot博客系统集成AI智能摘要功能实战
人工智能·spring boot·后端
96772 小时前
spring boot 终端运行指令以及这个查询端口是否被占用,以及释放端口的命令
java·spring boot·后端
XiYang-DING2 小时前
【Java SE】Java中的static关键字总结
java·开发语言
无心水2 小时前
【OpenClaw:认知启蒙】3、OpenClaw Agent执行循环(Lobster)深度拆解:从意图识别到工具调用的全流程
java·人工智能·系统架构·自动化
天空属于哈夫克32 小时前
Java 企微机器人开发:高性能、可扩展的私域自动化集成方案
java·机器人·企业微信
golang学习记2 小时前
IDEA 2026.1 EAP 4 发布:git操作更加丝滑了!
java·git·intellij-idea
一知半解仙2 小时前
AI加持下的IDEA让Java开发更高效
java·人工智能·intellij-idea
IT_陈寒2 小时前
JavaScript性能翻倍的5个隐藏技巧,90%的开发者都不知道!
前端·人工智能·后端