深入浅出讲解Spring框架中依赖注入与控制反转及应用
什么是依赖注入和控制反转
在传统的 Java 应用中,在一个类中如果需要依赖另一个类的对象,我们通常会使用“new”关键字手动创建这个对象。例如:
public class UserService {
private UserDao userDao = new UserDao();
// 其他方法
// ...
}
这种方式虽然简单,但是有一个缺点,就是这样耦合度高、扩展性差。例如如果 UserDao 的实现类需要变更,我们需要在所有依赖 UserDao 的业务类中修改代码。而且对于不同的环境,我们还需要手动修改代码。
此时依赖注入和控制反转就要登场了。
- 依赖注入(Dependency Injection)是指,通过引入 IoC 容器,在容器中动态加载对象,并将这些对象注入到需要使用它们的类中,从而实现对象与对象之间的解耦。
- 控制反转(Inversion of Control,IoC)是指,将对象的控制权由程序员转移到框架中,由框架帮我们管理对象的声明周期和依赖关系,从而实现程序的解耦。
Spring 中的依赖注入和控制反转
在 Spring 中,我们使用 BeanFactory 或者 ApplicationContext 容器来管理对象,并使用依赖注入来解决对象之间的依赖关系。
BeanFactory
在 Spring 中,BeanFactory 是一个很基础的容器,可以创建和管理对象。下面是一个示例:
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>
<bean id="userService" class="com.example.service.UserService">
<property name="userDao" ref="userDao"/>
</bean>
在这个示例中,我们创建了一个 UserDao 对象,并将其注入到 UserService 中。UserService 中的 userDao 属性使用 “property” 元素来注入,其中 “name” 表示属性名,ref=”userDao” 表示注入 userDao bean。
ApplicationContext
ApplicationContext 是一个更高级的容器,除了 BeanFactory 的所有功能外,还提供了更加方便的集成功能,例如国际化、事件处理、资源加载等。下面是一个示例:
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>
<bean id="userService" class="com.example.service.UserService"/>
在这个示例中,我们创建了一个 UserDao 对象,和一个 UserService 对象。注意,这里并没有显式地指定 UserDao 对象的注入方式,Spring 会自动检测 UserService 中的需要注入的属性,并自动注入相应的对象。
示例1:构建一个基础的 Spring 应用
接下来,我们将演示如何使用 Spring 的依赖注入和控制反转功能,构建一个简单的 Spring 应用程序。
步骤
首先,创建一个基础的 Spring 应用程序,包含以下文件和类:
- pom.xml:用于管理项目依赖。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
</dependencies>
- UserDao.java:创建一个 UserDao 接口。
public interface UserDao {
void save();
}
- UserDaoImpl.java:创建 UserDao 的实现类。
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("UserDaoImpl save method called");
}
}
- UserService.java:创建 UserService 接口。
public interface UserService {
void register();
}
- UserServiceImpl.java:创建 UserService 的实现类,并在其属性中注入 UserDao。
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void register() {
userDao.save();
System.out.println("UserServiceImpl register method called");
}
}
- applicationContext.xml:配置 Spring 容器。
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>
<bean id="userService" class="com.example.service.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
- Main.java:创建主函数用于测试应用程序。
public class Main {
public static void main(String[] args) {
// 加载配置文件
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取 UserService 实例
UserService userService = context.getBean(UserService.class);
// 调用 register 方法
userService.register();
// 关闭 Spring 容器
context.close();
}
}
实现过程
-
在 UserDao.java 中,我们创建了 UserDao 接口,其中定义了一个 save() 方法。
-
在 UserDaoImpl.java 中,我们创建了 UserDao 的实现类,并实现了 save() 方法。这个方法只是简单的打印一条消息,表示方法被调用了。
-
在 UserService.java 中,我们创建了 UserService 接口,并定义了一个 register() 方法。
-
在 UserServiceImpl.java 中,我们创建了 UserService 的实现类,并在其属性 userDao 中注入 UserDao 对象。在 register() 方法中,我们调用了 userDao 的 save() 方法,并打印了一条消息表示方法被调用了。
-
在 applicationContext.xml 中,我们配置了 Spring 容器,一共定义了两个 bean:userDao 和 userService。userService 中的 userDao 属性通过注入方式来实现。
-
在 Main.java 中,我们创建了主函数用于测试应用程序。我们加载了 applicationContext.xml 配置文件,并通过 context.getBean() 方法获取 UserService 实例。最后,调用 register() 方法,并关闭 Spring 容器。
到此为止,我们就完成了一个使用 Spring 的依赖注入和控制反转功能的简单应用程序。在运行程序时,我们可以看到控制台输出:
UserDaoImpl save method called
UserServiceImpl register method called
示例2:在 Spring Boot 应用程序中使用依赖注入
在 Spring Boot 应用程序中,Spring 自动配置了很多对象来简化我们的开发,我们只需要添加相关依赖,并在代码中注入相应的对象即可。
在这个示例中,我们将演示如何在 Spring Boot 应用程序中使用依赖注入。
步骤
首先,创建一个 Spring Boot 应用程序,包含以下文件和类:
- pom.xml:用于管理项目依赖。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.4.RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
- UserDao.java:创建一个 UserDao 接口。
public interface UserDao {
void save();
}
- UserDaoImpl.java:创建 UserDao 的实现类。
@Repository
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("UserDaoImpl save method called");
}
}
- UserService.java:创建 UserService 接口。
public interface UserService {
void register();
}
- UserServiceImpl.java:创建 UserService 的实现类,并使用 @Autowired 注解对 UserDao 进行注入。
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserDao userDao;
public void register() {
userDao.save();
System.out.println("UserServiceImpl register method called");
}
}
- Main.java:创建主函数用于测试应用程序。
@RestController
public class Main {
@Autowired
UserService userService;
@RequestMapping("/register")
public String register() {
userService.register();
return "success";
}
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
实现过程
-
在 UserDao.java 中,我们创建了 UserDao 接口,其中定义了一个 save() 方法。
-
在 UserDaoImpl.java 中,我们创建了 UserDao 的实现类,并使用 @Repository 注解将它声明为一个 bean。这个类中也实现了 save() 方法。
-
在 UserService.java 中,我们创建了 UserService 接口,并定义了一个 register() 方法。
-
在 UserServiceImpl.java 中,我们创建了 UserService 的实现类。这个类中使用 @Service 注解将其声明为一个 bean,并在 userDao 属性上使用 @Autowired 注解来进行注入。在 register() 方法中,我们调用了 userDao 的 save() 方法,并打印了一条消息表示方法被调用了。
-
在 Main.java 中,我们创建了主函数,并使用 @RestController 注解将其声明为一个 web 服务。在这个类中,我们将 UserService 注入到 userService 属性中,并编写了一个 /register 的接口用于测试服务。这个接口调用了 userService 的 register() 方法。
通过运行应用程序,我们可以在控制台上看到应用已经启动了。打开浏览器,输入 http://localhost:8080/register ,我们可以看到该接口调用了 UserServiceImpl 中的 register() 方法,并打印了一条消息表示方法被调用了。
至此,我们已经完成了如何在 Spring 应用程序和 Spring Boot 应用程序中使用依赖注入和控制反转的介绍。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入浅出讲解Spring框架中依赖注入与控制反转及应用 - Python技术站