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的程序入门
- 准备工作:创建Java工程,导入spring - context、commons - logging、log4j、junit等依赖坐标。
- 编写代码:编写接口和实现类,比如定义一个
UserService
接口及其实现类UserServiceImpl
。 - 配置文件:在src目录下创建Spring核心配置文件
applicationContext.xml
,配置需要管理的bean。像这样配置UserService
的实现类:
<bean id="userService" class="com.qcbyjy.service.UserServiceImpl"/>
- 配置日志:把
log4j.properties
配置文件拷贝到resources目录,作为日志配置文件。 - 测试代码:编写测试方法,通过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对象的三种方式
- 默认方式:使用无参数的构造方法,这是最常用的。例如:
<bean id="defaultBean" class="com.example.DefaultBean"/>
- 静态工厂实例化方式:通过静态工厂类的静态方法创建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"/>
- 实例工厂实例化方式:先创建实例工厂对象,再用工厂对象的方法创建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连接池。
- 创建工程并导入依赖:创建maven工程,导入spring - context、commons - logging、log4j、junit、druid、mysql - connector - java等jar包。
- 创建数据库和表结构:创建数据库和相关表,比如创建
spring_db
数据库和account
表。 - 编写代码:编写JavaBean类、
AccountDao
接口和实现类、AccountService
接口和实现类。 - 编写配置文件:配置文件管理Bean并配置连接池。
- 编写测试程序:验证功能是否正确。通过这个流程,能清晰了解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 常用的注解
- bean管理类注解:
@Component
用于普通类,@Controller
用于表现层,@Service
用于业务层,@Repository
用于持久层,它们作用相同,但建议在不同分层使用。 - 依赖注入注解:
@Value
注入普通类型,@Autowired
默认按类型自动装配引用类型,@Qualifier
和@Autowired
一起用能强制按名称注入,@Resource
是Java提供的注解,用name
属性按名称注入。 - 对象生命周期注解:
@Scope
定义对象生命周期,取值有singleton
(默认单实例)和prototype
(多例)。 - 初始化和销毁方法注解:
@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框架的优势,让代码更简洁、更易维护。希望大家在实际项目中多实践,熟练掌握这些知识,提升开发效率和代码质量!