注解篇
@ConfigurationProperties 注解的作用
在 Java 使用 Spring Framework 时,@ConfigurationProperties 注解常被用来管理配置文件(如 application.properties 或 application.yml)中的属性,以便将它们注入到 Spring 管理的 beans 中。这种机制提供了一种方便的方式来维护和使用配置数据,尤其是在需要配置多个属性的场景下
eg:
假设我们有以下的 application.yml 配置文件:
service:
providers:
firebase:
api-key: "your_api_key_here"
database-url: "https://your-database-url.firebaseio.com"
创建一个配置类来绑定这些属性:
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "service.providers.firebase")
public class FirebaseProperties {
private String apiKey;
private String databaseUrl;
}
使用配置类:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class FirebaseController {
@Autowired
private FirebaseProperties firebaseProperties;
@GetMapping("/firebase/config")
public String getFirebaseConfig() {
return "API Key: " + firebaseProperties.getApiKey() +
", Database URL: " + firebaseProperties.getDatabaseUrl();
}
}
@Service 注解的用法(在 Dubbo 中)注解的作用
在 Java 开发中,@Service 注解经常用于标注服务层的组件。当与 Apache Dubbo(一个高性能 Java RPC 框架)结合使用时,这个注解还担负起了将服务注册到 Dubbo 管理的 RPC 环境中的责任。Dubbo 扩展了 @Service 注解的功能,允许开发者指定更多参数来精确控制服务的注册与发现行为
参数解释
- **interfaceClass**:
用途:指定服务的接口类,这是其他服务消费者调用时的契约。
类型:Class<?>
例子:DubboCouponService.class 表示这个服务实现了 DubboCouponService 接口。
- **version**:
用途:定义服务的版本号。在一个接口有多个实现或者同一实现需要多版本共存时,可以通过版本号区分。
类型:String
例子:"1.0.0" 用于标识这个服务实现的具体版本。
- **group**:
用途:指定服务所属的组,可以用于区分处理相同服务接口的不同实例群组。
类型:String
例子:"yinni-marketing" 表示这个服务属于 "yinni-marketing" 组。
eg:
假设我们有一个服务接口 DubboCouponService,我们的实现类 DubboCouponServiceImpl 使用 @Service 注解进行标注
import org.apache.dubbo.config.annotation.Service;
import some.package.DubboCouponService;
@Service(
interfaceClass = DubboCouponService.class,
version = "1.0.0",
group = "yinni-marketing"
)
public class DubboCouponServiceImpl implements DubboCouponService {
// 实现接口中的方法
@Override
public void issueCoupon(String userId) {
System.out.println("Issuing coupon to user: " + userId);
}
}
使用情形:
- 版本管理:
在微服务架构中,服务的版本管理是一个常见需求。使用版本号(version),可以灵活地进行蓝绿部署或者滚动更新,同时保证服务的平稳过渡。 - 服务分组:
通过服务分组(group),可以在相同的服务接口下部署多个实例群组,这些群组可以基于地域、客户类型等因素进行区分。例如,针对不同的市场活动提供不同的优惠券发放策略。 - 接口明确化:
明确指定 interfaceClass 有助于 Dubbo 在运行时准确地绑定服务提供者与消费者,尤其是在接口类在多个包中有相同名称时。
@Transactional
eg:
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
在 Java 的 Spring 框架中,@Transactional 注解是用来管理事务的,它提供了一种声明式事务管理的方式。这意味着你可以通过声明的方式来控制事务的边界,而无需手动编写事务控制代码。@Transactional 注解可以应用于接口定义、接口方法、类定义、以及类公共方法上。使用这个注解可以极大地简化事务管理,使得开发者可以将更多的精力集中在业务逻辑上。
注解参数详解
@Transactional 注解的 propagation 和 rollbackFor 属性是控制事务行为的关键。
-
propagation 属性
propagation 属性用于设置事务的传播行为。传播行为可以理解为在一个事务方法被另一个事务方法调用时,这个事务应该如何进行。Spring 定义了多种传播行为,其中 Propagation.REQUIRES_NEW 表示该事务需要在一个新的事务中执行,如果当前存在一个事务,则先将这个现有的事务挂起。- Propagation.REQUIRES_NEW:
每次执行都会启动一个新的事务。
如果当前存在事务,将当前事务挂起。
使用场景:当一个操作需要保证其独立性,不被其他事务影响时使用,例如:日志记录。
- Propagation.REQUIRES_NEW:
-
rollbackFor 属性
rollbackFor 属性用于指定能够触发事务回滚的异常类型。Spring 默认情况下只会在遇到运行时异常(RuntimeException)和错误(Error)时才会触发事务回滚。- rollbackFor = Exception.class:
指定事务应该在遇到任何类型的 Exception 时回滚,而不仅仅是 RuntimeException。
使用场景:当你需要对业务逻辑中可能遇到的检查型异常也进行事务回滚时。
- rollbackFor = Exception.class:
假设我们有一个服务类,需要在执行中记录操作日志,无论主操作是否成功,日志记录都应该成功(即使主操作失败并回滚)。
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class TransactionalService {
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public void logAction(String action) {
// 日志记录操作,这里的事务独立于调用者的事务
logger.info("Action logged: " + action);
// 假设这里抛出了异常
if("error".equals(action)) {
throw new Exception("Simulated error");
}
}
@Transactional
public void performAction() {
try {
// 主要业务逻辑
businessService.perform();
// 日志记录,即使主业务失败,日志记录应该成功(因为使用REQUIRES_NEW)
logAction("Business action performed");
} catch (BusinessException e) {
logger.error("Business error occurred", e);
throw e; // 业务异常,将会导致事务回滚
}
}
}
使用 @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class) 注解可以确保方法在独立的新事务中执行,这对于需要隔离的事务操作(如日志记录)非常有用。此外,通过指定 rollbackFor = Exception.class,可以保证在任何异常发生时都会触发事务回滚,提高了代码的健壮性。
未完待续。。。。。