1. IOC与依赖注入的基本概念
1.1 什么是IOC?
IOC是一种设计原则,它将对象的创建和依赖关系的控制权从应用程序代码中转移到外部容器(如Spring容器)。通过IOC,开发者不再需要手动管理对象之间的依赖关系,而是由容器自动完成。
1.2 什么是依赖注入?
依赖注入是IOC的一种实现方式,它通过以下三种方式将依赖关系注入到对象中:
-
构造函数注入:通过构造函数传递依赖。
-
Setter方法注入:通过Setter方法传递依赖。
-
字段注入:通过反射直接注入字段(不推荐,因为破坏了封装性)。
2. Spring IOC的三种配置方式
Spring框架支持三种依赖注入的配置方式:
-
XML配置:传统的配置方式,适合老项目或需要高度解耦的场景。
-
注解配置:基于注解的配置方式,简化了配置,适合现代开发。
-
Java配置:通过Java类配置,完全摆脱XML,适合纯Java项目。
接下来,我们将通过示例详细介绍这三种方式。
3. XML配置方式
3.1 定义Bean
在XML配置文件中,使用<bean>
标签定义Bean,并通过<property>
或<constructor-arg>
注入依赖。
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 定义UserService Bean --><bean id="userService" class="com.example.service.UserService"><!-- 通过Setter方法注入UserRepository --><property name="userRepository" ref="userRepository"/></bean><!-- 定义UserRepository Bean --><bean id="userRepository" class="com.example.repository.UserRepository"/> </beans>
运行 HTML
3.2 编写Java类
// UserRepository.java public class UserRepository {public void save() {System.out.println("User saved!");} }// UserService.java public class UserService {private UserRepository userRepository;// Setter方法注入public void setUserRepository(UserRepository userRepository) {this.userRepository = userRepository;}public void performTask() {userRepository.save();} }
3.3 测试代码
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = context.getBean("userService", UserService.class);userService.performTask(); // 输出: User saved!} }
4. 注解配置方式
4.1 启用注解扫描
在XML配置文件中启用注解扫描:
<context:component-scan base-package="com.example"/>
运行 HTML
或者使用Java配置类启用注解扫描:
复制
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration;@Configuration @ComponentScan("com.example") public class AppConfig { }
4.2 使用注解定义Bean
Spring提供了以下常用注解:
-
@Component
:通用注解,用于标记类为Spring Bean。 -
@Service
:用于标记服务层组件。 -
@Repository
:用于标记数据访问层组件。 -
@Controller
:用于标记控制器层组件。
// UserRepository.java @Repository public class UserRepository {public void save() {System.out.println("User saved!");} }// UserService.java @Service public class UserService {@Autowired // 自动注入UserRepositoryprivate UserRepository userRepository;public void performTask() {userRepository.save();} }
4.3 测试代码
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = context.getBean(UserService.class);userService.performTask(); // 输出: User saved!} }
5. Java配置方式
5.1 定义配置类
使用@Configuration
注解标记配置类,并通过@Bean
注解定义Bean。
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;@Configuration public class AppConfig {@Beanpublic UserRepository userRepository() {return new UserRepository();}@Beanpublic UserService userService() {UserService userService = new UserService();userService.setUserRepository(userRepository()); // 手动注入依赖return userService;} }
5.2 编写Java类
// UserRepository.java public class UserRepository {public void save() {System.out.println("User saved!");} }// UserService.java public class UserService {private UserRepository userRepository;public void setUserRepository(UserRepository userRepository) {this.userRepository = userRepository;}public void performTask() {userRepository.save();} }
5.3 测试代码
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService userService = context.getBean(UserService.class);userService.performTask(); // 输出: User saved!} }
6. 依赖注入的三种方式
6.1 构造函数注入
@Service public class UserService {private final UserRepository userRepository;@Autowired // 构造函数注入public UserService(UserRepository userRepository) {this.userRepository = userRepository;}public void performTask() {userRepository.save();} }
6.2 Setter方法注入
@Service public class UserService {private UserRepository userRepository;@Autowired // Setter方法注入public void setUserRepository(UserRepository userRepository) {this.userRepository = userRepository;}public void performTask() {userRepository.save();} }
6.3 字段注入(不推荐)
@Service public class UserService {@Autowired // 字段注入private UserRepository userRepository;public void performTask() {userRepository.save();} }
7. 总结
Spring框架的IOC依赖注入功能极大地简化了对象之间的依赖管理,使代码更加模块化和可维护。通过XML配置、注解配置和Java配置三种方式,开发者可以根据项目需求选择最适合的配置方式。
-
XML配置:适合老项目或需要高度解耦的场景。
-
注解配置:简化配置,适合现代开发。
-
Java配置:完全摆脱XML,适合纯Java项目。
希望本文对你理解和使用Spring IOC依赖注入功能有所帮助。如果你有任何问题或建议,欢迎在评论区留言讨论!