Reputation: 53
I have this class:
@ApplicationScoped
public class BookService {
public boolean doorClosed;
public boolean isDoorClosed() {
return doorClosed;
}
}
And I have this test class:
@QuarkusTest
public class BookServiceTest {
@Inject BookService bookService;
@Test
public void testBookServiceDoor() throws InterruptedException {
bookService.doorClosed=true;
assertTrue(bookService.doorClosed);
assertTrue(bookService.isDoorClosed());
}
}
I am surprised that the last test assertion fails. The first passes but the last fails. It almost seems like that the getter/setters are using different variables than the one I am accessing directly.
I did the same test with Spring Boot and got the two assertions passing:
@Service
public class BookService {
public boolean doorClosed;
public boolean isDoorClosed() {
return doorClosed;
}
}
And the test:
@SpringBootTest
public class BookServiceTest {
@Autowired BookService bookService;
@Test
public void testBookServiceDoor() throws InterruptedException {
bookService.doorClosed=true;
assertTrue(bookService.doorClosed);
assertTrue(bookService.isDoorClosed());
}
}
Upvotes: 0
Views: 153
Reputation: 6587
Using the @ApplicationScoped
annotation makes the class a normal scoped bean. This means that the container never injects an actual instance of the class; instead, you get a proxy that will lookup the correct instance on each method invocation.
This is most commonly useful for example with @RequestScoped
beans, where you get a single proxy, which will dispatch method invocations to instances that belong to the "current request" (typically an HTTP request). However, there are good reasons why you might want this for application scoped beans as well (e.g. when you want lazy initialization).
The rule is: never access fields directly on normal scoped beans, only call methods.
If you want, you can make the class @Singleton
. That is a pseudo scope, and you get no proxy, you get the actual instance that you can work with directly.
Upvotes: 1