前提介绍
本文主要介绍相关Spring框架的一些新特性问题机制,包含了一些特定注解方面的认识。
@Lazy可以延迟依赖注入
@Lazy注解修饰在类层面!
@Lazy
@Service
public class UserService extends BaseService { }
可以把@Lazy放在@Autowired之上,即依赖注入也是延迟的;当我们调用userService时才会注入。即延迟依赖注入到使用时。同样适用于@Bean。
@Lazy
@Autowired
private UserService userService;
@Conditional
@Conditional类似于@Profile
一般用于如有开发环境、测试环境、正式机环境,为了方便切换不同的环境可以使用@Profile指定各个环境的配置。
通过某个配置来开启某个环境,方便切换,但是@Conditional的优点是允许自己定义规则,可以指定在如@Component、@Bean、@Configuration等注解的类上,以绝对Bean是否创建等。
首先来看看使用@Profile的用例,假设我们有个用户模块:
在测试/开发期间调用本机的模拟接口方便开发;
在部署到正式机时换成调用远程接口;
public abstract class UserService extends BaseService { }
@Profile(“local”)
@Service
public class LocalUserService extends UserService {}
@Profile(“remote”)
@Service
public class RemoteUserService extends UserService {}
我们在写测试用例时,可以指定我们使用哪个Profile:
@ActiveProfiles(“remote”)
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = “classpath:spring-config.xml”)
public class ServiceTest {
@Autowired
private UserService userService;
}
如果想自定义如@Profile之类的注解等,那么@Conditional就派上用场了,假设我们系统中有好多本地/远程接口,那么我们定义两个注解@Local和@Remote注解要比使用@Profile方便的多;如:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Conditional(CustomCondition.class)
public @interface Local { }
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Conditional(CustomCondition.class)
public @interface Remote {}
public class CustomCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
boolean isLocalBean = metadata.isAnnotated(“com.xxx.Local”);
boolean isRemoteBean = metadata.isAnnotated(“com.xxx.Remote”);
//如果bean没有注解@Local或@Remote,返回true,表示创建Bean
if(!isLocalBean && !isRemoteBean) {
return true;
}
boolean isLocalProfile = context.getEnvironment().acceptsProfiles(“local”);
//如果profile=local 且 bean注解了@Local,则返回true 表示创建bean
if(isLocalProfile) {
return isLocalBean;
}
// 否则默认返回注解了@Remote或没有注解@Remote的Bean
return isRemoteBean;
}
}
然后我们使用这两个注解分别注解我们的Service:
@Local
@Service
public class LocalUserService extends UserService { }
@Remote
@Service
public class RemoteUserService extends UserService {}
首先在@Local和@Remote注解上使用@Conditional(CustomCondition.class)指定条件。
然后使用@Local和@Remote注解我们的Service,这样当加载Service时,会先执行条件然后判断是否加载为Bean。
@Profile实现的Condition是:org.springframework.context.annotation.ProfileCondition。
AsyncRestTemplate非阻塞异步(已废弃WebClient代替之)
提供AsyncRestTemplate用于客户端非阻塞异步支持。
服务器端
@RestController
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping(“/api”)
public Callable api() {