当前位置: 首页 > news >正文

Spring框架核心知识全解析:从基础到实战

文章目录

  • 前言
  • 一、Spring框架概述
    • 1.1 框架定位
    • 1.2 核心价值
  • 二、Spring的IOC核心技术
    • 2.1 什么是IOC
    • 2.2 IOC的程序入门
    • 2.3 IOC技术总结
    • 2.4 Spring框架的Bean管理的配置文件方式
    • 2.5 实例化Bean对象的三种方式
  • 三、DI依赖注入
    • 3.1 依赖注入的概述
    • 3.2 属性的set方法注入值
    • 3.3 属性构造方法方式注入值
    • 3.4 数组,集合(List,Set,Map),Properties等的注入
  • 四、多配置文件方式
  • 五、Spring框架开发程序的方式
  • 六、IOC注解的方式
    • 6.1 IOC注解方式的快速入门
    • 6.2 常用的注解
    • 6.3 IOC纯注解的方式
  • 七、Spring框架整合JUnit单元测试
    • 7.1 Spring框架整合JUnit单元测试
    • 7.2 Spring整合单元测试(纯注解方式)
  • 总结


前言

在Java开发的广阔天地里,Spring框架就像一把万能钥匙,能轻松打开各种复杂项目的大门。它功能强大,能显著提升开发效率,降低开发难度。今天,咱们就一起深入探索Spring框架的核心技术,包括控制反转(IOC)、依赖注入(DI)、多配置文件管理、注解应用,还有与JUnit的整合测试。掌握这些技术,开发Java项目就会变得更加得心应手!


一、Spring框架概述

1.1 框架定位

  • 诞生背景:2003年由Rod Johnson创建,轻量级Java开发框架
  • 核心特性:基于控制反转(IoC)与面向切面(AOP)
  • 架构特点:分层架构设计,支持JavaSE/EE全栈开发

1.2 核心价值

  • 解耦架构:通过IoC容器管理对象生命周期,降低模块耦合度
  • 增强扩展性:利用AOP实现日志、权限等横切关注点模块化
  • 开发提效
    • 声明式事务管理(XML/注解配置)
    • 无缝整合JUnit测试框架
    • 集成MyBatis、Hibernate等主流技术栈
  • 简化复杂度:封装JDBC等复杂API,提升开发体验

二、Spring的IOC核心技术

2.1 什么是IOC

IOC,也就是控制反转,是一种很厉害的设计原则。在复杂的项目中,对象之间的依赖关系常常错综复杂,管理起来非常麻烦。IOC的出现解决了这个难题,它把对象的创建权交给Spring框架,这样代码的可维护性和扩展性都能大大增强。

2.2 IOC的程序入门

  1. 准备工作:创建Java工程,导入spring - context、commons - logging、log4j、junit等依赖坐标。
  2. 编写代码:编写接口和实现类,比如定义一个UserService接口及其实现类UserServiceImpl
  3. 配置文件:在src目录下创建Spring核心配置文件applicationContext.xml,配置需要管理的bean。像这样配置UserService的实现类:
<bean id="userService" class="com.qcbyjy.service.UserServiceImpl"/>
  1. 配置日志:把log4j.properties配置文件拷贝到resources目录,作为日志配置文件。
  2. 测试代码:编写测试方法,通过Spring的ApplicationContext工厂获取Bean对象,并调用其方法:
package com.qcbyjy.test;
import com.qcbyjy.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo1 {@Testpublic void run1(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = (UserService) applicationContext.getBean("userService");userService.hello();}
}

2.3 IOC技术总结

ApplicationContext是Spring中的工厂接口,通过它可以获取具体的Bean对象。它有两个常用的实现类:ClassPathXmlApplicationContext用于加载类路径下的Spring配置文件;FileSystemXmlApplicationContext用于加载本地磁盘下的Spring配置文件。开发时,根据配置文件的存放位置选择合适的实现类来创建ApplicationContext对象。

2.4 Spring框架的Bean管理的配置文件方式

在配置文件中管理Bean时,有几个重要属性:

  • id属性:给Bean起名字,必须唯一,名字要以字母开头,可以包含字母、数字、连字符等,但不能有特殊字符。
  • class属性:指定Bean对象的全路径。
  • scope属性:表示Bean的作用范围,常见取值有singleton(单例,默认值)、prototype(多例)、request(Web项目中,每次HTTP请求创建新Bean )、session(Web项目中,同一个HTTP Session共享一个Bean )。
  • init - method和destroy - method属性:可以配置Bean对象创建和销毁时调用的方法。

2.5 实例化Bean对象的三种方式

  1. 默认方式:使用无参数的构造方法,这是最常用的。例如:
<bean id="defaultBean" class="com.example.DefaultBean"/>
  1. 静态工厂实例化方式:通过静态工厂类的静态方法创建Bean对象。例如:
package com.qcbyjy.demo1;
import com.qcbyjy.service.UserService;
import com.qcbyjy.service.UserServiceImpl;
public class StaticFactory {public static UserService createUs(){System.out.println("通过静态工厂的方式创建UserServiceImpl对象...");return new UserServiceImpl();}
}

配置文件中这样写:

<bean id="us" class="com.qcbyjy.demo1.StaticFactory" factory-method="createUs"/>
  1. 实例工厂实例化方式:先创建实例工厂对象,再用工厂对象的方法创建Bean对象。配置如下:
<bean id="dfactory" class="com.qcbyjy.demo1.Dfactory"/>
<bean id="us" factory-bean="dfactory" factory-method="createUs"/>

三、DI依赖注入

3.1 依赖注入的概述

IOC强调对象创建权的反转,而DI(依赖注入)是在Spring框架创建Bean对象时,动态地把依赖对象注入到Bean组件中。比如OrderServiceImpl类依赖OrderDao ,通过DI,在创建OrderServiceImpl对象时,就会自动把OrderDao的实现类对象注入进去,让对象间的依赖关系更清晰,管理起来更方便。

3.2 属性的set方法注入值

编写需要注入值的属性,并提供对应的set方法,然后在配置文件中完成属性值注入。例如:

package com.qcbyjy.service;
import com.qcbyjy.dao.OrderDao;
public class OrderServiceImpl implements OrderService {private OrderDao orderDao;private String msg;private int age;public void setOrderDao(OrderDao orderDao) {this.orderDao = orderDao;}public void setMsg(String msg) {this.msg = msg;}public void setAge(int age) {this.age = age;}@Overridepublic void saveOrder() {System.out.println("业务层:保存订单..."+msg+" - "+age);orderDao.saveOrder();}
}

配置文件:

<bean id="os" class="com.qcbyjy.service.OrderServiceImpl"><property name="orderDao" ref="od"/><property name="msg" value="你好"/><property name="age" value="30"/>
</bean>
<bean id="od" class="com.qcbyjy.dao.OrderDaoImpl"></bean>

3.3 属性构造方法方式注入值

类成员变量也能通过构造函数注入。比如:

package com.qcbyjy.demo2;
public class Car {private String cname;private Double money;public Car(String cname, Double money) {this.cname = cname;this.money = money;}@Overridepublic String toString() {return "Car{" +"cname='" + cname + '\'' +", money=" + money +'}';}
}

配置文件:

<bean id="car" class="com.qcbyjy.demo2.Car"><constructor-arg name="cname" value="大奔"/><constructor-arg name="money" value="400000"/>
</bean>

3.4 数组,集合(List,Set,Map),Properties等的注入

在配置文件中能方便地为数组、集合、Map、Properties等属性注入值。例如:

package com.qcbyjy.demo3;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class CollectionBean {private String [] strs;private List<String> list;private Map<String,String> map;private Properties properties;public void setStrs(String[] strs) {this.strs = strs;}public void setList(List<String> list) {this.list = list;}public void setMap(Map<String, String> map) {this.map = map;}public void setProperties(Properties properties) {this.properties = properties;}@Overridepublic String toString() {return "CollectionBean{" +"strs=" + Arrays.toString(strs) +", list=" + list +", map=" + map +", properties=" + properties +'}';}
}

配置文件:

<bean id="collectionBean" class="com.qcbyjy.demo3.CollectionBean"><property name="strs"><array><value>美美</value><value>小凤</value></array></property><property name="list"><list><value>熊大</value><value>熊二</value></list></property><property name="map"><map><entry key="aaa" value="老王"/><entry key="bbb" value="小王"/></map></property><property name="properties"><props><prop key="username">root</prop><prop key="password">123456</prop></props></property>
</bean>

四、多配置文件方式

开发中可能会用到多个配置文件。加载多个配置文件有两种方法:一是在主配置文件中用<import resource="applicationContext2.xml"/>包含其他配置文件;二是创建ApplicationContext对象时直接加载多个配置文件,如ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml"); 。这种方式能让配置更模块化,管理和维护都更轻松。

五、Spring框架开发程序的方式

以一个简单需求为例,编写service和dao的类,持久层用原始的JDBC程序,连接池选Druid连接池。

  1. 创建工程并导入依赖:创建maven工程,导入spring - context、commons - logging、log4j、junit、druid、mysql - connector - java等jar包。
  2. 创建数据库和表结构:创建数据库和相关表,比如创建spring_db数据库和account表。
  3. 编写代码:编写JavaBean类、AccountDao接口和实现类、AccountService接口和实现类。
  4. 编写配置文件:配置文件管理Bean并配置连接池。
  5. 编写测试程序:验证功能是否正确。通过这个流程,能清晰了解Spring框架在实际项目中的应用。

六、IOC注解的方式

6.1 IOC注解方式的快速入门

使用IOC注解能更便捷地将类交给Spring容器管理。编写接口和实现类后,在需要管理的类上添加@Component注解。没指定名称时,默认用类名首字母小写作为Bean的ID,也能自己指定。例如:

package com.qcbyjy.demo2;
import org.springframework.stereotype.Component;
public interface UserService {public void hello();
}
@Component(value = "us")
public class UserServiceImpl implements UserService {@Overridepublic void hello() {System.out.println("Hello IOC注解...");}
}

接着在配置文件中开启注解扫描,指定扫描包路径:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.qcbyjy.demo2"/>
</beans>

最后编写测试方法获取Bean对象并调用其方法。

6.2 常用的注解

  1. bean管理类注解@Component用于普通类,@Controller用于表现层,@Service用于业务层,@Repository用于持久层,它们作用相同,但建议在不同分层使用。
  2. 依赖注入注解@Value注入普通类型,@Autowired默认按类型自动装配引用类型,@Qualifier@Autowired一起用能强制按名称注入,@Resource是Java提供的注解,用name属性按名称注入。
  3. 对象生命周期注解@Scope定义对象生命周期,取值有singleton(默认单实例)和prototype(多例)。
  4. 初始化和销毁方法注解@PostConstruct相当于init - method@PreDestroy相当于destroy - method

6.3 IOC纯注解的方式

在微服务架构开发中,纯注解方式很重要,它能替换所有配置文件,但需要编写配置类。编写实体类时用相关注解配置,如:

package com.qcbyjy.demo4;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class Order {@Value("北京")private String address;@Overridepublic String toString() {return "Order{" +"address='" + address + '\'' +'}';}
}

编写配置类替换applicationContext.xml ,用@Configuration声明配置类,@ComponentScan扫描指定包结构,@Import导入其他配置类,@Bean注解创建对象并保存到IOC容器。例如:

package com.qcbyjy.demo4;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value = "com.qcbyjy.demo4")
public class SpringConfig {
}

最后编写测试方法加载配置类并获取对象测试。

七、Spring框架整合JUnit单元测试

7.1 Spring框架整合JUnit单元测试

每次单元测试都手动编写创建工厂、加载配置文件等代码太繁琐。Spring提供了整合Junit单元测试的技术来简化流程。先要有Junit单元测试环境,即导入Junit单元测试的jar包,再导入spring - test的坐标依赖。接着编写测试类和方法,把类交给IOC容器管理,编写配置文件,最后编写测试代码。例如:

package com.qcbyjy.test;
import com.qcbyjy.demo5.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:applicationContext_test.xml")
public class Demo5 {@Autowiredprivate User user;@Testpublic void run1(){user.sayHello();}
}

7.2 Spring整合单元测试(纯注解方式)

纯注解方式整合单元测试也不难。编写类和方法,用@Component将类交给IOC容器管理,编写配置类用@Configuration@ComponentScan配置,最后编写测试方法加载配置类并测试。例如:

package com.qcbyjy.test;
import com.qcbyjy.demo6.SpringConfig6;
import com.qcbyjy.demo6.Customer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig6.class)
public class Demo6 {@Autowiredprivate Customer customer;@Testpublic void run1(){customer.save();}
}

总结

通过学习Spring框架的这些核心技术,我们在Java项目开发中就能更高效地利用Spring框架的优势,让代码更简洁、更易维护。希望大家在实际项目中多实践,熟练掌握这些知识,提升开发效率和代码质量!

http://www.xdnf.cn/news/382609.html

相关文章:

  • [面试]SoC验证工程师面试常见问题(六)高速接口篇
  • 含锡电镀废水深度净化技术体系解析化利用的全流程优化
  • pytest自动化测试执行环境切换的两种解决方案
  • 树莓派OS系统详解
  • 动态规划法:爬楼梯
  • C++模板梳理
  • JAVA练习题(3) 开发验证码
  • 如何避免软件腐朽
  • jflash下载时出现 Could not read unit serial number! 的解决方法
  • 数据结构—(概述)
  • 【typenum】 1 说明文件(README.md)
  • 【AI论文】迈向多模态通才之路:通用层级与通用基准
  • 一文讲透MCP的原理及实践
  • Kubernetes生产实战(十二):无工具容器网络连接数暴增指南
  • 【Day 24】HarmonyOS端云一体化开发:云函数
  • C PRIMER PLUS——第8节:字符串和字符串函数
  • 初等数论--欧拉定理及证明
  • 计算最短路径的数量模板(最短路)
  • 【智能指针】
  • 前端项目中单元测试与集成测试的管理实践
  • 基于51单片机的模拟洗衣机控制面板proteus仿真
  • JavaScript篇:async/await 错误处理指南:优雅捕获异常,告别失控的 Promise!
  • Java并发编程,从线程安全到死锁避免的实战解析
  • Java代码日志嵌入打包时间
  • 【排错】dify1.3.1插件市场安装报错问题
  • 《从零开始:构建你的第一个区块链应用》
  • 什么是文件描述符(File Descriptor,FD)
  • 45.中医知识问答管理员端对话信息查看功能bug修复(1)
  • 在 Vue 3 中实现刮刮乐抽奖
  • 进阶 DFS 学习笔记