小编dan*_*niu的帖子

Spring Hateoas ControllerLinkBuilder添加了空字段

我正在关注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)

java spring spring-hateoas spring-boot

12
推荐指数
1
解决办法
3996
查看次数

为什么调用方法不需要导入类?

我前几天偶然发现了一些奇怪的东西.

考虑以下代码(它收集给定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

java collections reference java-8 java-stream

9
推荐指数
1
解决办法
122
查看次数

为不同的配置文件定义具有相同方法名称的 Spring Bean

我有一个配置类,根据所选配置文件定义了两个 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 spring

8
推荐指数
2
解决办法
7222
查看次数

函数和谓词参数模糊不清?

使用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)

java functional-programming java-8

7
推荐指数
1
解决办法
246
查看次数

Wiremock 与 Spring Boot JUnit 5 测试:测试运行后使用的地址

我们有一个 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-boot wiremock junit5

7
推荐指数
1
解决办法
5282
查看次数

Mockito:如何模拟javax.inject.Provider创建的原型bean?

我有一个单例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方法可能很优雅吗?我还没有研究过。

java junit spring unit-testing mockito

5
推荐指数
1
解决办法
2835
查看次数

Spring Prototype-没有@Autowired的Bean Provider

我有一个原型 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;详情请参见下文。

java spring

5
推荐指数
1
解决办法
1479
查看次数

如何在测试规则中使JUnit测试失败

我有一些异步代码,可能会引发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)

junit junit4 kotlin

5
推荐指数
0
解决办法
158
查看次数

如何在 Kotlin 中模拟和验证 Lambda 表达式?

在 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 …

testing lambda mockito kotlin

5
推荐指数
1
解决办法
4400
查看次数

映射后的Java Stream to Array

我有以下代码,这是我偶然发现的一个简化版本:

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,我的选择是

  • 将接口从varargs更改为List
  • 我在代码示例中使用的演员
  • 向Mapper创建添加IntFunction

我缺少什么?你最喜欢什么?

java arrays generics java-stream

2
推荐指数
1
解决办法
338
查看次数