自学内容网 自学内容网

spring中service层是干嘛的

在Spring框架中,Service层是一个非常重要的组成部分,主要用于实现和封装应用程序的业务逻辑。以下是Service层的主要职责和特点:

主要职责

  1. 实现业务逻辑

    • Service层包含了应用程序的核心业务逻辑。例如,处理用户的注册、登录、订单生成等操作。
    • 这些业务逻辑通常涉及多个数据操作,Service层负责协调这些操作,确保业务逻辑的完整性和一致性。
  2. 事务管理

    • Service层通常负责管理事务,确保一系列数据库操作要么全部成功,要么全部失败。Spring提供了声明式事务管理,通过注解(如@Transactional)可以轻松地管理事务。
  3. 数据验证

    • 在进行业务操作之前,Service层可以对输入数据进行验证,确保数据的有效性和合法性。
  4. 调用数据访问层

    • Service层通常会调用DAO(Data Access Object)或Repository层的方法来执行具体的数据库操作。通过这种方式,Service层将业务逻辑与数据访问逻辑分离,提高了代码的可维护性和可测试性。
  5. 提供对外的API

    • Service层可以提供对外的服务接口,这些接口可以被Controller层调用,从而实现业务逻辑的封装和重用。

特点

  1. 解耦

    • Service层通过依赖注入(DI)与DAO层和Controller层解耦,使得各个层之间的依赖关系更加清晰,便于维护和扩展。
  2. 复用

    • Service层的方法可以被多个Controller方法调用,实现了业务逻辑的复用,避免了代码重复。
  3. 可测试性

    • Service层通常是一个独立的单元,可以很容易地编写单元测试来验证业务逻辑的正确性。
  4. 事务边界

    • Service层通常是事务的边界,事务管理通常在这个层进行配置,确保业务操作的原子性。

示例

以下是一个简单的Service层示例,展示了如何实现用户注册的业务逻辑:

@Service
@Transactional
public class UserService {

    @Autowired
    private UserRepository userRepository;

    /**
     * 用户注册
     * @param user 用户对象
     * @return 注册成功的用户对象
     */
    public User register(User user) {
        // 1. 验证用户输入
        if (user == null || user.getUsername() == null || user.getPassword() == null) {
            throw new IllegalArgumentException("Invalid user information");
        }

        // 2. 检查用户名是否已存在
        if (userRepository.findByUsername(user.getUsername()) != null) {
            throw new RuntimeException("Username already exists");
        }

        // 3. 加密密码
        String encryptedPassword = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(encryptedPassword);

        // 4. 保存用户到数据库
        return userRepository.save(user);
    }
}

总结

Service层在Spring框架中起到了连接Controller层和DAO层的桥梁作用,负责处理核心的业务逻辑,管理事务,验证数据,并提供可复用的服务接口。通过合理的分层设计,可以显著提高应用程序的可维护性和可扩展性。

@Transactional

是Spring框架提供的一个注解,用于声明式事务管理。它可以帮助开发者更方便地管理和控制事务,确保在执行数据库操作时,多个操作要么全部成功,要么全部失败,从而保证数据的一致性和完整性。以下是 @Transactional 注解的主要作用和使用方法:

主要作用

  1. 事务管理

    • @Transactional 注解可以应用于方法或类上,用于标记该方法或类中的所有方法需要在一个事务中执行。
    • 当方法被调用时,Spring会自动开启一个事务,并在方法执行完毕后根据结果提交或回滚事务。
  2. 保证数据一致性

    • 在执行多个数据库操作时,如果其中一个操作失败,事务会回滚,撤销所有已经执行的操作,确保数据的一致性。
    • 例如,在一个转账操作中,如果从账户A扣款成功,但在向账户B存款时失败,事务会回滚,撤销从账户A扣款的操作。
  3. 异常处理

    • 如果方法执行过程中抛出未捕获的异常,默认情况下事务会回滚。可以通过配置 @Transactional 注解来指定哪些异常会导致事务回滚,哪些异常不会导致事务回滚。

使用方法

1. 应用于方法上
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional
    public void transferMoney(Long fromUserId, Long toUserId, double amount) {
        // 从fromUserId账户扣款
        User fromUser = userRepository.findById(fromUserId).orElseThrow(() -> new RuntimeException("User not found"));
        fromUser.setBalance(fromUser.getBalance() - amount);
        userRepository.save(fromUser);

        // 向toUserId账户存款
        User toUser = userRepository.findById(toUserId).orElseThrow(() -> new RuntimeException("User not found"));
        toUser.setBalance(toUser.getBalance() + amount);
        userRepository.save(toUser);
    }
}
2. 应用于类上
@Service
@Transactional
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public void transferMoney(Long fromUserId, Long toUserId, double amount) {
        // 从fromUserId账户扣款
        User fromUser = userRepository.findById(fromUserId).orElseThrow(() -> new RuntimeException("User not found"));
        fromUser.setBalance(fromUser.getBalance() - amount);
        userRepository.save(fromUser);

        // 向toUserId账户存款
        User toUser = userRepository.findById(toUserId).orElseThrow(() -> new RuntimeException("User not found"));
        toUser.setBalance(toUser.getBalance() + amount);
        userRepository.save(toUser);
    }
}

配置选项

@Transactional 注解提供了多个属性,用于进一步控制事务的行为:

  • propagation:事务传播行为,默认值为 REQUIRED,表示如果有事务则加入当前事务,否则新建一个事务。
  • isolation:事务隔离级别,默认值为 DEFAULT,表示使用数据库的默认隔离级别。
  • readOnly:是否只读事务,默认值为 false,表示读写事务。
  • timeout:事务超时时间,默认值为 -1,表示使用全局事务超时时间。
  • rollbackFor:指定哪些异常会导致事务回滚,默认情况下运行时异常(RuntimeException)会导致事务回滚。
  • noRollbackFor:指定哪些异常不会导致事务回滚。

示例

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false, timeout = 30, rollbackFor = Exception.class)
    public void transferMoney(Long fromUserId, Long toUserId, double amount) {
        // 从fromUserId账户扣款
        User fromUser = userRepository.findById(fromUserId).orElseThrow(() -> new RuntimeException("User not found"));
        fromUser.setBalance(fromUser.getBalance() - amount);
        userRepository.save(fromUser);

        // 向toUserId账户存款
        User toUser = userRepository.findById(toUserId).orElseThrow(() -> new RuntimeException("User not found"));
        toUser.setBalance(toUser.getBalance() + amount);
        userRepository.save(toUser);
    }
}

总结

@Transactional 注解是Spring框架中用于声明式事务管理的重要工具。通过在方法或类上添加 @Transactional 注解,可以轻松地控制事务的行为,确保数据库操作的原子性和一致性。这不仅简化了事务管理的代码,也提高了应用程序的可靠性和可维护性。


原文地址:https://blog.csdn.net/qq_43518966/article/details/143692537

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!