我正在关注Spring REST的教程,并试图将HATEOAS链接添加到我的Controller结果中.
我有一个简单的User类和一个CRUD控制器.
class User {
private int id;
private String name;
private LocalDate birthdate;
// and getters/setters
}
Run Code Online (Sandbox Code Playgroud)
服务:
@Component
class UserService {
private static List<User> users = new ArrayList<>();
List<User> findAll() {
return Collections.unmodifiableList(users);
}
public Optional<User> findById(int id) {
return users.stream().filter(u -> u.getId() == id).findFirst();
}
// and add and delete methods of course, but not important here
}
Run Code Online (Sandbox Code Playgroud)
一切正常,除了我的控制器,我想从所有用户列表添加链接到单个用户:
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/users")
public …Run Code Online (Sandbox Code Playgroud) 我前几天偶然发现了一些奇怪的东西.
考虑以下代码(它收集给定Strings 的不同字长计数,但这并不重要):
static void collectByLambda(Collection<String> list) {
Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(String::length),
m -> m.keySet()
));
}
Run Code Online (Sandbox Code Playgroud)
及其等效方法参考版本:
static void collectByMethodReference(Collection<String> list) {
Collection<Integer> collected = list.stream().collect(Collectors.collectingAndThen(
Collectors.groupingBy(String::length),
Map::keySet
));
}
Run Code Online (Sandbox Code Playgroud)
第一个(lambda)版本不需要你import java.util.Map编译,第二个版本.
这究竟是为什么?我可以想象这是因为第二个版本需要Map在编译时访问类来构建引用; 但Map#keySet()如果它不导入,它怎么知道甚至存在Map?
我有一个配置类,根据所选配置文件定义了两个 bean,并覆盖了配置方法:
@Configuration
class MyConfig {
@Profile("profile")
@Bean
MyBean myBean(MyBeanProperties properties) {
return new MyBean(properties);
}
@Profile("!profile")
@Bean
MyBean myBean(MyBeanProperties properties, AdditionalProperties addProps) {
MyBean result = new MyBean(properties);
result.addAdditionalProperties(addProps);
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
MyBean和一个自动装配到其中的类
@Service
class MyService {
MyBean autowiredBean;
private MyService(MyBean bean) { this.autowiredBean = bean; }
}
Run Code Online (Sandbox Code Playgroud)
现在,当我启动 Spring 上下文时,它失败并显示消息
com.example.MyServce 中构造函数的参数 0 需要类型为“com.example.MyBean”的 bean,但无法找到。
这怎么可能?我清楚地定义了 Spring bean,因此它应该在创建上下文时出现。
使用Java 8,我得到以下代码的编译器错误:
public class Ambiguous {
public static void call() {
SomeDataClass data = new SomeDataClass();
callee(data, SomeDataClass::getString);
// compiler errors:
// 1. at callee method name:
// The method callee(SomeDataClass, Function<SomeDataClass,String>) is ambiguous for the type Ambiguous
// 2. at lambda:
// Type mismatch: cannot convert from boolean to String
callee(data, d -> d.getRandom() > 0.5);
}
public static void callee(SomeDataClass data, Function<SomeDataClass, String> extractString) {
System.out.println(extractString.apply(data));
}
public static void callee(SomeDataClass data, Predicate<SomeDataClass> check) {
System.out.println(check.test(data));
}
} …Run Code Online (Sandbox Code Playgroud) 我们有一个 Spring Boot 2.2.0.RELEASE 应用程序,我们正在使用 WireMock 使用 JUnit 5 测试类对其进行测试。测试在本地运行良好,但在我们的 Jenkins 上,它在测试成功运行后失败并显示“地址已在使用中”消息。
这是我们的 spring 依赖项pom.xml:
<properties>
<java.version>11</java.version>
<spring-cloud.version>Hoxton.RC2</spring-cloud.version>
<spring-cloud-stream.version>3.0.0.RC2</spring-cloud-stream.version>
<openapi.codegen.maven.plugin.version>4.1.2</openapi.codegen.maven.plugin.version>
<jacoco-maven-plugin.version>0.8.4</jacoco-maven-plugin.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<!-- Utils -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator</artifactId>
<version>${openapi.codegen.maven.plugin.version}</version>
</dependency>
<!-- Testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion> …Run Code Online (Sandbox Code Playgroud) 我有一个单例Spring bean,它创建原型bean。这些是从javax.inject.Provider字段中检索的:
@Component
public class MySingleton {
@Autowired
private javax.inject.Provider<MyPrototype> prototypeFactory;
public void doStuff() {
MyPrototype bean = prototypeFactory.get();
bean.invoke();
}
}
@Component
@Scope("prototype")
public class MyPrototype {
public void invoke() {}
}
Run Code Online (Sandbox Code Playgroud)
现在,我想为Singleton创建一个JUnit-Test:
@Mock
MyPrototype prototype;
@InjectMocks
MySingleton sut;
@Test
public void testPrototype() {
sut.doStuff();
verify(prototype, times(1)).invoke();
}
Run Code Online (Sandbox Code Playgroud)
但这可以理解为无法正确设置Singleton's Provider。
有什么办法吗?我想避免创建创建Prototype实例的Singleton Factory bean。
或者,使用@LookupSingleton 的-factory方法可能很优雅吗?我还没有研究过。
我有一个原型 Bean,它由带有以下内容的单例 bean 实例化Provider:
@Component
@Scope("prototype")
class MyPrototype {}
@Component
class MySingleton {
@Autowired
javax.inject.Provider<MyPrototype> prototypeFactory;
}
Run Code Online (Sandbox Code Playgroud)
这很好用,但我们公司规定@Autowired不允许这样做;常见的模式是@Resource(SingletonBeanClass.BEAN_ID).
是否可以通过Provider这种方式进行注释,以便 Spring 查找可以创建它?
我知道我可以使用@Lookup或单例工厂 bean 添加工厂方法,但我更喜欢Provider.
编辑:我没有让它以这种方式工作,最后不得不编辑spring.xml;详情请参见下文。
我有一些异步代码,可能会引发JUnit错过的异常(因此测试通过)。
我创建了一个TestRule将这些异常收集到列表中。任何测试完成后,断言将遍历列表,并且如果异常列表为非空,则测试将失败。
我想在异常发生后立即通过测试,而不是在测试完成后失败。这可以用吗?TestRule
我的 TestRule
/**
* Coroutines can throw exceptions that can go unnoticed by the JUnit Test Runner which will pass
* a test that should have failed. This rule will ensure the test fails, provided that you use the
* [CoroutineContext] provided by [dispatcher].
*/
class CoroutineExceptionRule : TestWatcher(), TestRule {
private val exceptions = Collections.synchronizedList(mutableListOf<Throwable>())
val dispatcher: CoroutineContext
get() = Unconfined + CoroutineExceptionHandler { _, throwable ->
// I …Run Code Online (Sandbox Code Playgroud) 在 Kotlin(和 Java 8)中,我们可以使用 Lambda 表达式来移除样板回调接口。例如,
data class Profile(val name: String)
interface ProfileCallback {
fun onSuccess(profile: Profile)
}
class ProfileRepository(val callback: ProfileCallback) {
fun getProfile() {
// do calculation
callback.onSuccess(Profile("name"))
}
}
Run Code Online (Sandbox Code Playgroud)
我们可以把removeProfileCallback改成Kotlin的Lambda:
class ProfileRepository(val callback: (Profile) -> Unit) {
fun getProfile() {
// do calculation
callback(Profile("name"))
}
}
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我不确定如何模拟然后验证该功能。我试过像这样使用 Mockito
@Mock
lateinit var profileCallback: (Profile) -> Unit
@Test
fun test() {
// this wouldn't work
Mockito.verify(profileCallback).invoke(any())
}
Run Code Online (Sandbox Code Playgroud)
但它抛出一个异常:
org.mockito.exceptions.base.MockitoException: ClassCastException 在创建 mockito 模拟时发生:要模拟的类:'kotlin.jvm.functions.Function1',由类加载器加载:'sun.misc.Launcher$AppClassLoader@7852e922'
如何在 Kotlin 中模拟和验证 Lambda …
我有以下代码,这是我偶然发现的一个简化版本:
public class Transforming
{
static interface MyInterface<T>
{
void consume(T... toConsume);
}
static abstract class Mapper<T> implements MyInterface<String> {
MyInterface<T> delegate;
public Mapper(MyInterface<T> delegateTo)
{
delegate = delegateTo;
}
public void consume(String... transformFrom)
{
T[] array = (T[]) Arrays.stream(transformFrom)
.map(this::transform)
.toArray(); // can't toArray(T[]::new) here!
delegate.consume(array);
}
protected abstract T transform(String toTransform);
}
}
Run Code Online (Sandbox Code Playgroud)
关于如何将流转换为数组的搜索明显不足,因为此时我没有生成的数组类型,并且Java不允许我创建泛型类型的数组...
我确实理解这个问题,但有关如何清理代码的任何输入?AFAICT,我的选择是
我缺少什么?你最喜欢什么?
java ×7
spring ×4
java-8 ×2
java-stream ×2
junit ×2
kotlin ×2
mockito ×2
spring-boot ×2
arrays ×1
collections ×1
generics ×1
junit4 ×1
junit5 ×1
lambda ×1
reference ×1
testing ×1
unit-testing ×1
wiremock ×1