news 2026/8/28 16:32:15

Spring全面详解(基础版)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring全面详解(基础版)
文章目录*一、Spring简介* * 1.1 Spring是什么 * 1.2 Spring的优势 * 1.3 Spring的体系结构* 二、Spring快速入门* * 2.1Spring程序开发步骤与原始步骤相比较 * 2.2 Sping程序开发步骤(第一个Spring程序)* 三、Spring相关API* * 3.1 ApplicationContext * 3.2 getBean()方法* 四、Spring配置文件* * 4.1 Bean标签基本配置 * 4.2 Bean标签范围配置 * 4.3 Bean生命周期配置 * 4.4 Bean实例化四种方式 * **4.5 Bean的依赖注入 * * 4.5.1 依赖注入的概念 * 4.5.2 Bean依赖注入入门例子 * 4.5.3 Bean的依赖注入方式 * 4.5.4 Bean依赖注入的数据类型 * * 4.5.4.1普通数据类型的注入: * 4.5.4.2 集合数据类型的注入 * 4.6 引入其他配置文件(分模块开发)* 五、Spring注解开发* * 5.1 Spring原始注解 * 5.2 Spring新注解* 六、Spring集成Junit* * 6.1 问题引入 * 6.2 Spring集成Junit步骤一、Spring简介----------### 1.1 Spring是什么Spring是分层的Java SE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切面编程)为内核。提供了展现层SpringMVC持久层SpringJDBCTemplate以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的JavaEE企业应用开源框架。### 1.2 Spring的优势**(1)方便解耦,简化开发通过 Spring 提供的 IOC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度耦合。用户也不必再为单例模式 类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。(2)AOP编程的支持通过 Spring的 AOP 功能,方便进行面向切面编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松实现。(3)声明式事务的支持可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务管理,提高开发效率和质量。(4)方便程序的测试可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。(5)方便继承各种优秀框架Spring对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的支持。(6)降低JavaEEAPI的使用难度Spring对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。(7)Java源码是经典学习范例Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java 设计模式灵活运用以及对 Java技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。### 1.3 Spring的体系结构如上图所示,Spring 由多个模块组成,它们可以分为核心容器(Core Container)、数据访问/集 成(Data Access/Integration)、Web、面向切面编程(AOP, Aspect Oriented Programming)、设备(Instrumentation)、消息发送(Messaging)和测试(Test)。二、Spring快速入门------------### 2.1Spring程序开发步骤与原始步骤相比较(1)不使用Spring**(2)使用Spring### 2.2 Sping程序开发步骤(第一个Spring程序)第一步:创建一个普通得maven项目,项目名称为SpringDemo第二步:导入Spring开发的基本包坐标org.springframework spring-context 5.2.9.RELEASE第三步:编写Dao接口和实现类package org.example.dao; public interface UserDao { public void save(); }package org.example.dao.impl; import org.example.dao.UserDao; public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println(“UserDao’s save method is running…”); } }第四步:创建Spring核心配置文件:在类路径resources下创建applicationContext.xml配置文件<?xml version="1.0" encoding="UTF-8"?>第五步:在Spring配置文件中配置UserDaoImpl第六步:测试,使用Spring的API获得Bean实例@Test public void testFirstIocDemo() { //读取核心配置文件,加载应用上下文,可通过其获得Spring容器中的Bean对象 ApplicationContext app = new ClassPathXmlApplicationContext(“applicationContext.xml”); //通过getBean方法获取容器内的bean对象 UserDao userDao = (UserDao) app.getBean(“userDao”); //调用userDao的save方法 userDao.save(); }三、Spring相关API-------------### 3.1 ApplicationContextapplicationContext:接口类型,代表应用上下文,可以通过其实例获得 Spring 容器中的 Bean 对象。其实现类有以下三个:*ClassPathXmlApplicationContext:它是从类的根路径下加载配置文件 推荐使用这种 *FileSystemXmlApplicationContext: 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。 *AnnotationConfigApplicationContext:当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。 ### 3.2 getBean()方法 //第一种:当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转 public Object getBean(String name) throws BeansException assertBeanFactoryActive(); return getBeanFactory().getBean(name); } //第二种:当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错 public T getBean(Class requiredType) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(requiredType); } 四、Spring配置文件------------### 4.1 Bean标签基本配置bean标签用于配置对象交由Spring来创建,默认情况下它调用的是类中的无参构造器,如果没有无参构造函数则不能创建成功。基本属性:(1)id:Bean实例在Spring容器中的唯一标识**(2)class**:Bean的全限定名称### 4.2 Bean标签范围配置scope:指对象的作用范围,取值如下:取值范围说明singleton默认值,单例的prototype****多例的requestWEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中sessionWEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中global sessionWEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境那么globalSession 相当于 session(1)当scope的取值为singleton时:Bean的实例化个数:1个Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例Bean的生命周期:对象创建:当应用加载,创建容器时,对象就被创建了对象运行:只要容器在,对象一直活着对象销毁:当应用卸载,销毁容器时,对象就被销毁了(2)当scope的支取为prototype时:Bean的实例化个数:多个Bean的实例化时机:当调用getBean()方法时实例化BeanBean的生命周期:对象创建:当使用对象时,创建新的对象实例对象运行:只要对象在使用中,就一直活着对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收了### 4.3 Bean生命周期配置(1)init-method:指定类中的初始化方法名称(2)destroy-method:指定类中销毁方法名称### 4.4 Bean实例化四种方式#### * 无参构造方法实例化:它会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败 * 有参的构造方法实例化: * 工厂静态方法实例化: //工厂的静态方法返回Bean实例 public class StaticFactory { public static UserDao createUserDao() { return new UserDaoImpl(); } } * 工厂实例方法实例化: //工厂的非静态方法返回Bean实例 public class DynamicFactory { public UserDao createUserDao() { return new UserDaoImpl(); } } ### 4.5 Bean的依赖注入#### 4.5.1 依赖注入的概念依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。#### 4.5.2 Bean依赖注入入门例子* 创建业务逻辑接口UserService和其实现类UserServiceImpl,在内部调用UserDao的save方法。 public class UserServiceImpl implements UserService { @Override public void save() { //获取UserDao对象,调用其save方法 //读取核心配置文件,加载应用上下文,可通过其获得Spring容器中的Bean对象 ApplicationContext app = new ClassPathXmlApplicationContext(“applicationContext.xml”); //通过getBean方法获取容器内的bean对象 UserDao userDao = (UserDao) app.getBean(“userDao”); //调用userDao的save方法 userDao.save(); } } * 将UserServiceImpl的创建权交给Spring * 从Spring容器获得UserService进行操作 @Test /测试依赖注入/ public void testDIDemo() { ApplicationContext app = new ClassPathXmlApplicationContext(“applicationContext.xml”); UserService userService = (UserService) app.getBean(“userService”); userService.save(); } 分析:上述代码中,UserService实例和UserDao实例都存在与Spring容器中,当前的做法是在容器外部获得UserService实例和UserDao实例,然后在程序中进行结合。优化方案:因为UserService和UserDao都在Spring容器中,而最终程序直接使用的是UserService,所以可以在Spring容器中,将UserDao设置到UserService内部。问题:怎么将UserDao注入到UserService内部呢?#### 4.5.3 Bean的依赖注入方式**(1)方式一:set方法*** 在UserServiceImpl中添加setUserDao方法 public class UserServiceImpl implements UserService { UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save() { userDao.save(); } } * 配置Spring容器中调用set方法进行注入(2)方式二:构造方法注入* 创建有参构造器 public class UserServiceImpl implements UserService { UserDao userDao; public UserServiceImpl(UserDao userDao) { this.userDao=userDao; } public UserServiceImpl() { } public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void save() { userDao.save(); } } * 配置Spring容器调用有参构造方法进行注入 #### 4.5.4 Bean依赖注入的数据类型上面的操作,都是注入的引用Bean,除了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。注入的类型可分为三种:*普通数据类型*引用数据类型(参考3.5.3) *集合数据类型##### 4.5.4.1普通数据类型的注入:* 创建User类 public class User { private String name; private int age; private String address; public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return “User{” + “name='” + name + ‘’’ + “, age=” + age + “, address='” + address + ‘’’ + ‘}’; } } * 配置普通数据类型的属性注入: * 测试: @Test /测试普通数据类型的注入/ public void testDIDemo2() { ApplicationContext app = new ClassPathXmlApplicationContext(“applicationContext.xml”); User user = (User) app.getBean(“user1”); System.out.println(user); } ##### 4.5.4.2 集合数据类型的注入(1)List的注入 public class UserDaoImpl implements UserDao { private List strList; public void setStrList(List strList) { this.strList = strList; } @Override public void save() { System.out.println(“strList=”+strList); System.out.println(“UserDao’s save method is running…”); } } 111 222 333 444 (2)List的注入 public class UserDaoImpl implements UserDao { private List userList; public void setUserList(List userList) { this.userList = userList; } @Override public void save() { System.out.println(“userList=”+userList); System.out.println(“UserDao’s save method is running…”); } } (3)Map<String,User>的注入 public class UserDaoImpl implements UserDao { private Map<String,User> userMap; public void setUserMap(Map<String, User> userMap) { this.userMap = userMap; } @Override public void save() { System.out.println(“userMap=”+userMap); System.out.println(“UserDao’s save method is running…”); } } (4)Properties的注入 public class UserDaoImpl implements UserDao { private Properties properties; public void setProperties(Properties properties) { this.properties = properties; } @Override public void save() { System.out.println(“properties=”+properties); System.out.println(“UserDao’s save method is running…”); } } aaa bbb ccc ### 4.6 引入其他配置文件(分模块开发)实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载。 五、Spring注解开发------------### 5.1 Spring原始注解Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。Spring原始注解主要是替代的配置,常用注解如下:注解****说明@Component使用在类上用于实例化Bean@Controller使用在web层类上用于实例化Bean@Service使用在service层类上用于实例化Bean@Repository使用在dao层类上用于实例化Bean@Autowired使用在字段上用于根据类型依赖注入@Qualifier结合@Autowired一起使用用于根据名称进行依赖注入@Resource相当于@Autowired+@Qualifier,按照名称进行注入@Value注入普通属性@Scope标注Bean的作用范围@PostConstruct使用在方法上标注该方法是Bean的初始化方法@PreDestroy使用在方法上标注该方法是Bean的销毁方法注意:使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法。 <?xml version="1.0" encoding="UTF-8"?> <context:component-scan base-package=“net.togogo”></context:component-scan> ### 5.2 Spring新注解使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下: 非自定义的Bean的配置: 加载properties文件的配置:context:property-placeholder 组件扫描的配置:context:component-scan 引入其他配置文件:注解****说明@Configuration用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解@ComponentScan用于指定 Spring 在初始化容器时要扫描的包。 作用和在 Spring 的 xml 配置文件中的 <context:component-scan base-package=“com.itheima”/>一样@Bean使用在方法上,标注将该方法的返回值存储到 Spring 容器中@PropertySource用于加载.properties 文件中的配置@Import用于导入其他配置类 @Configuration @ComponentScan(“net.togogo”) @Import(SpringConfigTwo.class) public class SpringConfigOne { @Bean(“myuser”) public User getUser() { return new User(); } } @Configuration @PropertySource(“classpath:test.properties”) public class SpringConfigTwo { @Value(“u s e r n a m e " ) p r i v a t e S t r i n g n a m e ; @ V a l u e ( " {user_name}") private String name; @Value("username")privateStringname;@Value("{user_age}”) private int age; @Value(“${user_address}”) private String address; @Bean(“userDao”) public UserDao getUserDao() { return new UserDaoImpl(name,age,address); } } @Test /测试Spring的新注解/ public void testNewAnnotation() { ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfigOne.class); User myuser = (User) app.getBean(“myuser”); System.out.println(myuser); UserDao userDao = (UserDao) app.getBean(“userDao”); userDao.save(); } 六、Spring集成Junit---------------### 6.1 问题引入在测试类中,每个测试方法都有以下两行代码: ApplicationContext app = new ClassPathXmlApplicationContext(“applicationContext.xml”); User user = (User) app.getBean(“user1”); 这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。如何优化?上述问题的解决思路:让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它将需要进行测试Bean直接在测试类中进行注入### 6.2 Spring集成Junit步骤①导入spring集成Junit的坐标 org.springframework spring-test 5.2.9.RELEASE junit junit 4.12 ②使用@Runwith注解替换原来的运行期:@RunWith(SpringJUnit4ClassRunner.class)使用了Spring的SpringJUnit4ClassRunner,以便在测试开始的时候自动创建Spring的应用上下文。③使用@ContextConfiguration指定配置文件或配置类④使用@Autowired注入需要测试的对象⑤创建测试方法进行测试 @RunWith(SpringJUnit4ClassRunner.class) //加载核心配置文件或者核心配置类 //@ContextConfiguration(value = {“classpath:applicationContext.xml”}) @ContextConfiguration(classes = {SpringConfigOne.class}) public class SpringIOCTest { @Autowired @Qualifier(“myuser”) private User user; @Autowired @Qualifier(“userDao”) private UserDao userDao; @Test public void testNewAnnotation() { System.out.println(user); userDao.save(); } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 16:31:16

Node+Express+MySQL可上线脚手架工程实践

简介&#xff1a;Express 是轻量级 Node.js Web 框架的工业标准&#xff0c;其简洁中间件模型与 MySQL 关系型数据库构成稳定后端技术基座&#xff1b;理解 Express 路由机制、MySQL 连接池配置及环境变量安全注入&#xff0c;是构建高可用服务的关键基础。该技术组合兼顾开发效…

作者头像 李华
网站建设 2026/8/28 16:31:12

C++函数模板实战:从基础数组最大值到现代泛型编程进阶

1. 项目概述&#xff1a;为什么我们需要模板来求数组最大值&#xff1f;在C开发中&#xff0c;处理数组并找出其中的最大值是一个基础得不能再基础的操作。新手可能会为每种数据类型写一个独立的函数&#xff0c;比如findMaxInt、findMaxDouble、findMaxString。但稍微有点经验…

作者头像 李华
网站建设 2026/8/28 16:28:54

数学建模竞赛必备:MATLAB核心基础与实战工具箱应用指南

1. 项目概述&#xff1a;为什么数学建模绕不开MATLAB&#xff1f;如果你正准备参加数学建模竞赛&#xff0c;或者你的课程、科研项目里涉及到数学建模&#xff0c;那你大概率已经听过MATLAB这个名字了。很多新手朋友拿到题目&#xff0c;第一反应可能是&#xff1a;“我该用Pyt…

作者头像 李华