Code samples and tests for the article "What's New in Spring 4.3?" (#497)
* Spring 4.3 New features in Spring 4.3 * Added Spring-4.3 as a new module Added Spring-4.3 as a new module. * Adding read file Adding read file * Re-written examples as tests * Added attribute annotations and default methods
This commit is contained in:
parent
41bf1d2f21
commit
7e8f3e6f15
2
pom.xml
2
pom.xml
@ -77,7 +77,7 @@
|
||||
<module>spring-zuul</module>
|
||||
<module>jsf</module>
|
||||
<module>xml</module>
|
||||
|
||||
<module>spring-4.3</module>
|
||||
<module>lombok</module>
|
||||
<module>redis</module>
|
||||
|
||||
|
9
spring-4.3/README.md
Normal file
9
spring-4.3/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
In this tutorial we cover few of the new features of Spring 4.3:
|
||||
|
||||
|
||||
Implicit Constructor Injection
|
||||
Improved Resolution of Dependency
|
||||
Cache Abstraction Refinements
|
||||
Composed @RequestMapping Variants
|
||||
@RequestScope, @SessionScope, @ApplicationScope annotations
|
||||
Libraries/Application Servers Versions Support
|
122
spring-4.3/pom.xml
Normal file
122
spring-4.3/pom.xml
Normal file
@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-4.3</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Spring 4.3 Demo</name>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-tx</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-jdbc</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.1.0.Final</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.1.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
<version>3.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<version>1.4.190</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-framework-bom</artifactId>
|
||||
<version>4.3.1.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,14 @@
|
||||
package com.baeldung.spring43.attributeannotations;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/test")
|
||||
public class AttributeAnnotationsTestController {
|
||||
|
||||
@GetMapping
|
||||
public String get(@SessionAttribute String login, @RequestAttribute String query) {
|
||||
return String.format("login = %s, query = %s", login, query);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.baeldung.spring43.attributeannotations;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
public class ParamInterceptor extends HandlerInterceptorAdapter {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
request.getSession().setAttribute("login", "john");
|
||||
request.setAttribute("query", "invoices");
|
||||
return super.preHandle(request, response, handler);
|
||||
}
|
||||
|
||||
}
|
29
spring-4.3/src/main/java/com/baeldung/spring43/cache/Foo.java
vendored
Normal file
29
spring-4.3/src/main/java/com/baeldung/spring43/cache/Foo.java
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
package com.baeldung.spring43.cache;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class Foo {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(Foo.class);
|
||||
|
||||
private static final AtomicInteger instanceCount = new AtomicInteger(0);
|
||||
|
||||
|
||||
private final int instanceNum;
|
||||
|
||||
public Foo() {
|
||||
instanceNum = instanceCount.incrementAndGet();
|
||||
}
|
||||
|
||||
public static int getInstanceCount() {
|
||||
return instanceCount.get();
|
||||
}
|
||||
|
||||
public void printInstanceNumber() {
|
||||
log.info("Foo instance number: {}", instanceNum);
|
||||
}
|
||||
|
||||
}
|
14
spring-4.3/src/main/java/com/baeldung/spring43/cache/FooService.java
vendored
Normal file
14
spring-4.3/src/main/java/com/baeldung/spring43/cache/FooService.java
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
package com.baeldung.spring43.cache;
|
||||
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class FooService {
|
||||
|
||||
@Cacheable(cacheNames = "foos", sync = true)
|
||||
public Foo getFoo(String id) {
|
||||
return new Foo();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.baeldung.spring43.composedmapping;
|
||||
|
||||
public class Appointment {
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.baeldung.spring43.composedmapping;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface AppointmentService {
|
||||
|
||||
Map<String, Appointment> getAppointmentsForToday();
|
||||
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.baeldung.spring43.composedmapping;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/appointments")
|
||||
public class AppointmentsController {
|
||||
|
||||
private final AppointmentService appointmentService;
|
||||
|
||||
@Autowired
|
||||
public AppointmentsController(AppointmentService appointmentService) {
|
||||
this.appointmentService = appointmentService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Map<String, Appointment> get() {
|
||||
return appointmentService.getAppointmentsForToday();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.baeldung.spring43.ctor;
|
||||
|
||||
public class FooRepository {
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.baeldung.spring43.ctor;
|
||||
|
||||
public class FooService {
|
||||
|
||||
private final FooRepository repository;
|
||||
|
||||
public FooService(FooRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
public FooRepository getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.baeldung.spring43.defaultmethods;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
public class DateHolder implements IDateHolder {
|
||||
|
||||
private LocalDate localDate;
|
||||
|
||||
@Override
|
||||
public LocalDate getLocalDate() {
|
||||
return localDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocalDate(LocalDate localDate) {
|
||||
this.localDate = localDate;
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.baeldung.spring43.defaultmethods;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
public interface IDateHolder {
|
||||
|
||||
LocalDate getLocalDate();
|
||||
|
||||
void setLocalDate(LocalDate localDate);
|
||||
|
||||
default void setStringDate(String stringDate) {
|
||||
setLocalDate(LocalDate.parse(stringDate, DateTimeFormatter.ofPattern("dd.MM.yyyy")));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.baeldung.spring43.depresolution;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public class FooRepository {
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.baeldung.spring43.depresolution;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class FooService {
|
||||
|
||||
private final FooRepository repository;
|
||||
|
||||
public FooService(ObjectProvider<FooRepository> repositoryProvider) {
|
||||
this.repository = repositoryProvider.getIfUnique();
|
||||
}
|
||||
|
||||
public FooRepository getRepository() {
|
||||
return repository;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.baeldung.spring43.scopeannotations;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.annotation.ApplicationScope;
|
||||
|
||||
@Component
|
||||
@ApplicationScope
|
||||
public class AppPreferences extends InstanceCountingService {
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.baeldung.spring43.scopeannotations;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class InstanceCountingService {
|
||||
|
||||
private static final AtomicInteger instanceCount = new AtomicInteger(0);
|
||||
|
||||
private final int instanceNumber = instanceCount.incrementAndGet();
|
||||
|
||||
public int getInstanceNumber() {
|
||||
return instanceNumber;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.baeldung.spring43.scopeannotations;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.annotation.RequestScope;
|
||||
|
||||
@Component
|
||||
@RequestScope
|
||||
public class LoginAction extends InstanceCountingService {
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package com.baeldung.spring43.scopeannotations;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/appointments")
|
||||
public class ScopeTestController {
|
||||
|
||||
@Autowired
|
||||
private LoginAction loginAction;
|
||||
|
||||
@Autowired
|
||||
private UserPreferences userPreferences;
|
||||
|
||||
@Autowired
|
||||
private AppPreferences appPreferences;
|
||||
|
||||
@GetMapping("/request")
|
||||
public String getRequestNumber() {
|
||||
return Integer.toString(loginAction.getInstanceNumber());
|
||||
}
|
||||
|
||||
@GetMapping("/session")
|
||||
public String getSessionNumber() {
|
||||
return Integer.toString(userPreferences.getInstanceNumber());
|
||||
}
|
||||
|
||||
@GetMapping("/application")
|
||||
public String getApplicationNumber() {
|
||||
return Integer.toString(appPreferences.getInstanceNumber());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.baeldung.spring43.scopeannotations;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.annotation.SessionScope;
|
||||
|
||||
@Component
|
||||
@SessionScope
|
||||
public class UserPreferences extends InstanceCountingService {
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.baeldung.spring43.attributeannotations;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@EnableWebMvc
|
||||
public class AttributeAnnotationConfiguration extends WebMvcConfigurerAdapter {
|
||||
|
||||
@Bean
|
||||
public ViewResolver viewResolver() {
|
||||
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
|
||||
viewResolver.setPrefix("/WEB-INF/jsp/view/");
|
||||
viewResolver.setSuffix(".jsp");
|
||||
return viewResolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new ParamInterceptor());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.baeldung.spring43.attributeannotations;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@ContextConfiguration(classes = AttributeAnnotationConfiguration.class)
|
||||
@WebAppConfiguration
|
||||
public class AttributeAnnotationTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext wac;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenInterceptorAddsRequestAndSessionParams_thenParamsInjectedWithAttributesAnnotations() throws Exception {
|
||||
String result = this.mockMvc.perform(get("/test")
|
||||
.accept(MediaType.ALL))
|
||||
.andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
|
||||
Assert.assertEquals("login = john, query = invoices", result);
|
||||
}
|
||||
|
||||
}
|
25
spring-4.3/src/test/java/com/baeldung/spring43/cache/CacheRefinementsConfiguration.java
vendored
Normal file
25
spring-4.3/src/test/java/com/baeldung/spring43/cache/CacheRefinementsConfiguration.java
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package com.baeldung.spring43.cache;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.cache.concurrent.ConcurrentMapCache;
|
||||
import org.springframework.cache.support.SimpleCacheManager;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@EnableCaching
|
||||
public class CacheRefinementsConfiguration {
|
||||
|
||||
@Bean
|
||||
public CacheManager cacheManager() {
|
||||
SimpleCacheManager manager = new SimpleCacheManager();
|
||||
manager.setCaches(Collections.singletonList(new ConcurrentMapCache("foos")));
|
||||
return manager;
|
||||
}
|
||||
|
||||
}
|
31
spring-4.3/src/test/java/com/baeldung/spring43/cache/CacheRefinementsTest.java
vendored
Normal file
31
spring-4.3/src/test/java/com/baeldung/spring43/cache/CacheRefinementsTest.java
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
package com.baeldung.spring43.cache;
|
||||
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@ContextConfiguration(classes = CacheRefinementsConfiguration.class)
|
||||
public class CacheRefinementsTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
private ExecutorService executorService = Executors.newFixedThreadPool(10);
|
||||
|
||||
@Autowired
|
||||
private FooService service;
|
||||
|
||||
@Test
|
||||
public void whenMultipleThreadsExecuteCacheableMethodWithSyncTrue_thenMethodIsExecutedOnlyOnce() throws InterruptedException {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
executorService.execute(() -> service.getFoo("test").printInstanceNumber());
|
||||
}
|
||||
executorService.awaitTermination(1, TimeUnit.SECONDS);
|
||||
assertEquals(Foo.getInstanceCount(), 1);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.baeldung.spring43.composedmapping;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
|
||||
import static org.easymock.EasyMock.*;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@EnableWebMvc
|
||||
public class ComposedMappingConfiguration {
|
||||
|
||||
@Bean
|
||||
public ViewResolver viewResolver() {
|
||||
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
|
||||
viewResolver.setPrefix("/WEB-INF/jsp/view/");
|
||||
viewResolver.setSuffix(".jsp");
|
||||
return viewResolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AppointmentService appointmentBook() {
|
||||
AppointmentService book = mock(AppointmentService.class);
|
||||
expect(book.getAppointmentsForToday()).andReturn(Collections.emptyMap());
|
||||
replay(book);
|
||||
return book;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.baeldung.spring43.composedmapping;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@ContextConfiguration(classes = ComposedMappingConfiguration.class)
|
||||
@WebAppConfiguration
|
||||
public class ComposedMappingTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
@Autowired
|
||||
private AppointmentService appointmentService;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext wac;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenRequestingMethodWithGetMapping_thenReceiving200Answer() throws Exception {
|
||||
this.mockMvc.perform(get("/appointments")
|
||||
.accept(MediaType.ALL))
|
||||
.andExpect(status().isOk());
|
||||
verify(appointmentService);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.baeldung.spring43.ctor;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@ContextConfiguration(classes = {FooRepositoryConfiguration.class, FooServiceConfiguration.class})
|
||||
public class ConfigurationConstructorInjectionTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
@Autowired
|
||||
public FooService fooService;
|
||||
|
||||
@Test
|
||||
public void whenSingleCtorInConfiguration_thenContextLoadsNormally() {
|
||||
assertNotNull(fooService.getRepository());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.baeldung.spring43.ctor;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class FooRepositoryConfiguration {
|
||||
|
||||
@Bean
|
||||
public FooRepository fooRepository() {
|
||||
return new FooRepository();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.baeldung.spring43.ctor;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class FooServiceConfiguration {
|
||||
|
||||
private final FooRepository repository;
|
||||
|
||||
public FooServiceConfiguration(FooRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FooService fooService() {
|
||||
return new FooService(this.repository);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.baeldung.spring43.ctor;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@ContextConfiguration("classpath:implicit-ctor-context.xml")
|
||||
public class ImplicitConstructorTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
@Autowired
|
||||
private FooService fooService;
|
||||
|
||||
@Test
|
||||
public void whenBeanWithoutAutowiredCtor_thenInjectIntoSingleCtor() {
|
||||
assertNotNull(fooService.getRepository());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.baeldung.spring43.defaultmethods;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@ContextConfiguration("classpath:defaultmethods-context.xml")
|
||||
public class DefaultMethodsInjectionTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
@Autowired
|
||||
private IDateHolder dateHolder;
|
||||
|
||||
@Test
|
||||
public void whenInjectingToDefaultInterfaceMethod_thenInjectionShouldHappen() {
|
||||
assertEquals(LocalDate.of(1982, 10, 15), dateHolder.getLocalDate());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.baeldung.spring43.defaultmethods;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.test.context.transaction.AfterTransaction;
|
||||
import org.springframework.test.context.transaction.BeforeTransaction;
|
||||
|
||||
public interface ITransactionalTest {
|
||||
|
||||
Logger log = LoggerFactory.getLogger(ITransactionalTest.class);
|
||||
|
||||
@BeforeTransaction
|
||||
default void beforeTransaction() {
|
||||
log.info("Opening transaction");
|
||||
}
|
||||
|
||||
@AfterTransaction
|
||||
default void afterTransaction() {
|
||||
log.info("Closing transaction");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.baeldung.spring43.defaultmethods;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
|
||||
|
||||
@ContextConfiguration(classes = TransactionalTestConfiguration.class)
|
||||
public class TransactionalTest extends AbstractTransactionalJUnit4SpringContextTests implements ITransactionalTest {
|
||||
|
||||
@Test
|
||||
public void whenDefaultMethodAnnotatedWithBeforeTransaction_thenDefaultMethodIsExecuted() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package com.baeldung.spring43.defaultmethods;
|
||||
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
|
||||
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
|
||||
@Configuration
|
||||
public class TransactionalTestConfiguration {
|
||||
|
||||
@Bean
|
||||
public DataSource getDataSource() {
|
||||
SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
|
||||
simpleDriverDataSource.setDriverClass(org.h2.Driver.class);
|
||||
simpleDriverDataSource.setUrl("jdbc:h2:mem:~test");
|
||||
simpleDriverDataSource.setUsername("sa");
|
||||
simpleDriverDataSource.setPassword("");
|
||||
return simpleDriverDataSource;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager transactionManager() {
|
||||
return new DataSourceTransactionManager(getDataSource());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.baeldung.spring43.depresolution;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
public class ObjectProviderConfiguration {
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.baeldung.spring43.depresolution;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
@ContextConfiguration(classes = ObjectProviderConfiguration.class)
|
||||
public class ObjectProviderTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
@Autowired
|
||||
private FooService fooService;
|
||||
|
||||
@Test
|
||||
public void whenArgumentIsObjectProvider_thenObjectProviderInjected() {
|
||||
|
||||
assertNotNull(fooService.getRepository());
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.baeldung.spring43.scopeannotations;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan
|
||||
@EnableWebMvc
|
||||
public class ScopeAnnotationsConfiguration {
|
||||
|
||||
@Bean
|
||||
public ViewResolver viewResolver() {
|
||||
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
|
||||
viewResolver.setPrefix("/WEB-INF/jsp/view/");
|
||||
viewResolver.setSuffix(".jsp");
|
||||
return viewResolver;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package com.baeldung.spring43.scopeannotations;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@ContextConfiguration(classes = ScopeAnnotationsConfiguration.class)
|
||||
@WebAppConfiguration
|
||||
public class ScopeAnnotationsTest extends AbstractJUnit4SpringContextTests {
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private WebApplicationContext wac;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDifferentRequests_thenDifferentInstancesOfRequestScopedBeans() throws Exception {
|
||||
MockHttpSession session = new MockHttpSession();
|
||||
|
||||
String requestScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/request")
|
||||
.session(session)
|
||||
.accept(MediaType.ALL)).andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
|
||||
String requestScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/request")
|
||||
.session(session)
|
||||
.accept(MediaType.ALL)).andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
|
||||
assertNotEquals(requestScopedServiceInstanceNumber1, requestScopedServiceInstanceNumber2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDifferentSessions_thenDifferentInstancesOfSessionScopedBeans() throws Exception {
|
||||
|
||||
MockHttpSession session1 = new MockHttpSession();
|
||||
MockHttpSession session2 = new MockHttpSession();
|
||||
|
||||
String sessionScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/session")
|
||||
.session(session1)
|
||||
.accept(MediaType.ALL)).andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
String sessionScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/session")
|
||||
.session(session1)
|
||||
.accept(MediaType.ALL)).andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
String sessionScopedServiceInstanceNumber3 = this.mockMvc.perform(get("/appointments/session")
|
||||
.session(session2)
|
||||
.accept(MediaType.ALL)).andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
|
||||
assertEquals(sessionScopedServiceInstanceNumber1, sessionScopedServiceInstanceNumber2);
|
||||
|
||||
assertNotEquals(sessionScopedServiceInstanceNumber1, sessionScopedServiceInstanceNumber3);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDifferentSessionsAndRequests_thenAlwaysSingleApplicationScopedBean() throws Exception {
|
||||
|
||||
MockHttpSession session1 = new MockHttpSession();
|
||||
MockHttpSession session2 = new MockHttpSession();
|
||||
|
||||
String applicationScopedServiceInstanceNumber1 = this.mockMvc.perform(get("/appointments/application")
|
||||
.session(session1)
|
||||
.accept(MediaType.ALL)).andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
String applicationScopedServiceInstanceNumber2 = this.mockMvc.perform(get("/appointments/application")
|
||||
.session(session2)
|
||||
.accept(MediaType.ALL)).andExpect(status().isOk())
|
||||
.andReturn()
|
||||
.getResponse()
|
||||
.getContentAsString();
|
||||
|
||||
assertEquals(applicationScopedServiceInstanceNumber1, applicationScopedServiceInstanceNumber2);
|
||||
|
||||
}
|
||||
|
||||
}
|
10
spring-4.3/src/test/resources/defaultmethods-context.xml
Normal file
10
spring-4.3/src/test/resources/defaultmethods-context.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="dateHolder" class="com.baeldung.spring43.defaultmethods.DateHolder">
|
||||
<property name="stringDate" value="15.10.1982"/>
|
||||
</bean>
|
||||
|
||||
</beans>
|
10
spring-4.3/src/test/resources/implicit-ctor-context.xml
Normal file
10
spring-4.3/src/test/resources/implicit-ctor-context.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean class="com.baeldung.spring43.ctor.FooRepository"/>
|
||||
|
||||
<bean class="com.baeldung.spring43.ctor.FooService"/>
|
||||
|
||||
</beans>
|
32
spring-4.3/src/test/resources/logback.xml
Normal file
32
spring-4.3/src/test/resources/logback.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<layout class="ch.qos.logback.classic.PatternLayout">
|
||||
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p: %c - %m%n</Pattern>
|
||||
</layout>
|
||||
</appender>
|
||||
|
||||
<!-- Application Loggers -->
|
||||
<logger name="com.baeldung">
|
||||
<level value="debug"/>
|
||||
</logger>
|
||||
|
||||
<!-- Spring Loggers -->
|
||||
<logger name="org.springframework.core">
|
||||
<level value="info"/>
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.beans">
|
||||
<level value="info"/>
|
||||
</logger>
|
||||
|
||||
<logger name="org.springframework.context">
|
||||
<level value="info"/>
|
||||
</logger>
|
||||
|
||||
<root level="warn">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
Loading…
x
Reference in New Issue
Block a user