spring 依赖注入的好处

spring框架通过依赖注入,对象之间的依赖关系由 Spring 容器来管理,而不是在代码中硬编码。

这意味着一个类不再需要自己创建和管理其依赖的对象,而是由 Spring 容器将依赖的对象注入到类中

例如:

在一个用户管理系统中,UserService 类依赖于 UserDao 类,使用 Spring 的依赖注入,UserService 类不需要在内部使用 new 关键字创建 UserDao 的实例,而是由 Spring 容器将 UserDao 的实例注入到 UserService 中。这样,UserService 与 UserDao 的实现细节解耦,当 UserDao 的实现发生变化时,UserService 类不需要进行修改。

场景一:更换 UserDao 的实现类

原理

Spring 的自动注入基于依赖倒置原则,让 UserService 依赖于抽象(接口)而非具体实现当需要更换 UserDao 实现类时,只需在 Spring 的配置中调整注入的具体实现类,而 UserService 类本身依赖的是抽象接口,不会受到实现类更换的影响。

代码示例

1. 定义 UserDao 接口
// UserDao 接口,定义用户数据访问的方法
public interface UserDao {
    void saveUser();
}
2. 实现 UserDao 接口
// 旧的 UserDao 实现类
import org.springframework.stereotype.Repository;

@Repository
public class OldUserDao implements UserDao {
    @Override
    public void saveUser() {
        System.out.println("使用旧方法保存用户信息");
    }
}

// 新的 UserDao 实现类
import org.springframework.stereotype.Repository;

@Repository
public class NewUserDao implements UserDao {
    @Override
    public void saveUser() {
        System.out.println("使用新方法保存用户信息");
    }
}
3. 定义 UserService 类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    private UserDao userDao;

    @Autowired
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }

    public void createUser() {
        userDao.saveUser();
    }
}

在 UserService 类中,构造函数通过 @Autowired 注解注入 UserDao 接口的实现类。UserService 只依赖于 UserDao 接口,不关心具体是哪个实现类。

4. Spring 配置类(使用 Java 配置)
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    // 这里可以选择注入旧的实现类
    // @Bean
    // public UserDao userDao() {
    //     return new OldUserDao();
    // }

    // 也可以选择注入新的实现类
    @Bean
    public UserDao userDao() {
        return new NewUserDao();
    }

    @Bean
    public UserService userService(UserDao userDao) {
        return new UserService(userDao);
    }
}

场景二:UserDao 构造函数发生变化

代码示例

首先,我们有一个简单的 UserDao 类和 UserService 类,UserService 类手动创建 UserDao 实例。

// UserDao 类,用于处理用户数据访问
class UserDao {
    public UserDao() {
        System.out.println("UserDao 实例被创建");
    }

    public void saveUser() {
        System.out.println("保存用户信息");
    }
}

// UserService 类,用于处理用户业务逻辑,依赖于 UserDao
class UserService {
    private UserDao userDao;

    public UserService() {
        this.userDao = new UserDao();
    }

    public void createUser() {
        userDao.saveUser();
    }
}

// 测试类
public class Main {
    public static void main(String[] args) {
        UserService userService = new UserService();
        userService.createUser();
    }
}

在这个初始代码中,UserService 类的构造函数里手动使用 new 关键字创建了 UserDao 实例。

构造函数变化

现在,假设 UserDao 的需求发生了变化,需要在构造函数中传入一个数据库连接字符串。

// 修改后的 UserDao 类,构造函数需要传入数据库连接字符串
class UserDao {
    private String dbConnectionString;

    public UserDao(String dbConnectionString) {
        this.dbConnectionString = dbConnectionString;
        System.out.println("UserDao 实例被创建,使用数据库连接字符串: " + dbConnectionString);
    }

    public void saveUser() {
        System.out.println("使用 " + dbConnectionString + " 保存用户信息");
    }
}

// UserService 类,由于 UserDao 构造函数变化,需要修改
class UserService {
    private UserDao userDao;

    public UserService() {
        // 这里需要修改,因为 UserDao 构造函数发生了变化
        this.userDao = new UserDao("jdbc:mysql://localhost:3306/mydb");
    }

    public void createUser() {
        userDao.saveUser();
    }
}

// 测试类
public class Main {
    public static void main(String[] args) {
        UserService userService = new UserService();
        userService.createUser();
    }
}

可以看到,由于 UserDao 的构造函数发生了变化,UserService 类的构造函数也必须进行修改,这就体现了 UserService 与 UserDao 实现细节的紧密耦合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值