What’s New in Spring 4.3? – Spring 4.3有什么新内容?

最后修改: 2016年 7月 14日

1. Overview


The Spring 4.3 release brought some nice refinements into core container, caching, JMS, Web MVC and testing submodules of the framework.

Spring 4.3版本为框架的核心容器、缓存、JMS、Web MVC和测试子模块带来了一些不错的改进。

In this post, we will discuss few of these improvements including:


  • Implicit Constructor Injection
  • Java 8 Default Interface Methods Support
  • Improved Resolution of Dependencies
  • Cache Abstraction Refinements
  • Composed @RequestMapping Variants
  • @Requestscope, @Sessionscope, @Applicationscope Annotations
  • @RequestAttribute and @SessionAttribute annotations
  • Libraries/Application Servers Versions Support
  • the InjectionPoint class

2. Implicit Constructor Injection


Consider the following service class:


public class FooService {

    private final FooRepository repository;

    public FooService(FooRepository repository) {
        this.repository = repository

Quite a common use case, but if you forget the @Autowired annotation on the constructor, the container will throw an exception looking for a default constructor, unless you explicitly do the wiring.


So as of 4.3, you no longer need to specify an explicit injection annotation in such a single-constructor scenario. This is particularly elegant for classes which do not carry any annotations at all:


public class FooService {

    private final FooRepository repository;

    public FooService(FooRepository repository) {
        this.repository = repository

In Spring 4.2 and below, the following configuration for this bean will not work, because Spring will not be able to find a default constructor for FooService. Spring 4.3 is smarter and will autowire the constructor automatically:

在Spring 4.2及以下版本中,该Bean的以下配置将不起作用,因为Spring将无法找到FooService的默认构造函数。Spring 4.3更聪明,会自动连接构造函数。

    <bean class="com.baeldung.spring43.ctor.FooRepository" />
    <bean class="com.baeldung.spring43.ctor.FooService" />

Similarly, you may have noticed that @Configuration classes historically did not support constructor injection. As of 4.3, they do, and they naturally allow omitting @Autowired in a single-constructor scenario as well:

同样地,你可能已经注意到,@Configuration类在历史上不支持构造函数注入。从 4.3 版开始,它们支持,而且它们自然也允许在单一构造器的情况下省略 @Autowired

public class FooConfiguration {

    private final FooRepository repository;

    public FooConfiguration(FooRepository repository) {
        this.repository = repository;

    public FooService fooService() {
        return new FooService(this.repository);

3. Java 8 Default Interface Methods Support

3.Java 8默认接口方法支持

Before Spring 4.3, default interface methods were not supported.

在Spring 4.3之前,不支持默认接口方法。

This was not easy to implement because even JDK’s JavaBean introspector did not detect default methods as accessors. Since Spring 4.3, getters and setters implemented as default interface methods are identified during injection, which allows to use them for instance as common preprocessors for accessed properties, like in this example:

这并不容易实现,因为即使是JDK的JavaBean自省器也没有检测到默认方法作为访问器。从Spring 4.3开始,作为默认接口方法实现的getters和setters会在注入过程中被识别出来,这样就可以把它们作为访问属性的普通预处理器,就像本例中一样。

public interface IDateHolder {

    void setLocalDate(LocalDate localDate);

    LocalDate getLocalDate();

    default void setStringDate(String stringDate) {


This bean may now have the stringDate property injected:


<bean id="dateHolder" 
    <property name="stringDate" value="15.10.1982"/>

Same goes for using test annotations like @BeforeTransaction and @AfterTransaction on default interface methods. JUnit 5 already supports its test annotations on default interface methods, and Spring 4.3 follows the lead. Now you can abstract common testing logic in an interface and implement it in test classes. Here is an interface for test cases that logs messages before and after transactions in tests:

在默认接口方法上使用@BeforeTransaction@AfterTransaction等测试注释也是如此。JUnit 5已经支持其在默认接口方法上的测试注解,而Spring 4.3也紧随其后。现在你可以在一个接口中抽象出常见的测试逻辑,并在测试类中实现它。下面是一个测试用例的接口,在测试中记录事务前后的信息。

public interface ITransactionalTest {

    Logger log = LoggerFactory.getLogger(ITransactionalTest.class);

    default void beforeTransaction() {
        log.info("Before opening transaction");

    default void afterTransaction() {
        log.info("After closing transaction");


Another improvement concerning annotations @BeforeTransaction, @AfterTransaction and @Transactional is the relaxation of the requirement that the annotated methods should be public — now they may have any visibility level.

关于注释@BeforeTransaction, @AfterTransaction@Transactional的另一项改进是放宽了注释方法应该是public的要求–现在它们可以有任何可见性级别。

4. Improved Resolution of Dependencies


The newest version also introduces the ObjectProvider, an extension of the existing ObjectFactory interface with handy signatures such as getIfAvailable and getIfUnique to retrieve a bean only if it exists or if a single candidate can be determined (in particular: a primary candidate in case of multiple matching beans).


public class FooService {

    private final FooRepository repository;

    public FooService(ObjectProvider<FooRepository> repositoryProvider) {
        this.repository = repositoryProvider.getIfUnique();

You may use such ObjectProvider handle for custom resolution purposes during initialization as shown above, or store the handle in a field for late on-demand resolution (as you typically do with an ObjectFactory).


5. Cache Abstraction Refinements


The cache abstraction is mainly used to cache values that are CPU and IO consuming. In particular use cases, a given key may be requested by several threads (i.e. clients) in parallel, especially on startup. Synchronized cache support is a long-requested feature that has now been implemented. Assume the following:


public class FooService {

    @Cacheable(cacheNames = "foos", sync = true)
    public Foo getFoo(String id) { ... }


Notice the sync = true attribute which tells the framework to block any concurrent threads while the value is being computed. This will make sure that this intensive operation is invoked only once in case of concurrent access.

请注意sync = true属性,它告诉框架在计算值的时候要阻止任何并发线程。这将确保在并发访问的情况下,这个密集操作只被调用一次。

Spring 4.3 also improves the caching abstraction as follows:

Spring 4.3还改进了缓存抽象,具体如下。

  • SpEL expressions in cache-related annotations can now refer to beans (i.e. @beanName.method()).
  • ConcurrentMapCacheManager and ConcurrentMapCache now support the serialization of cache entries via a new storeByValue attribute.
  • @Cacheable, @CacheEvict, @CachePut, and @Caching may now be used as meta-annotations to create custom composed annotations with attribute overrides.

6. Composed @RequestMapping Variants


Spring Framework 4.3 introduces the following method-level composed variants of the @RequestMapping annotation that help to simplify mappings for common HTTP methods and better express the semantics of the annotated handler method.

Spring Framework 4.3引入了以下@RequestMapping注解的方法级组成变体,有助于简化常见HTTP方法的映射,并更好地表达注解的处理方法的语义。

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

For example, @GetMapping is a shorter form of saying @RequestMapping(method = RequestMethod.GET). The following example shows an MVC controller that has been simplified with a composed @GetMapping annotation.

例如,@GetMapping@RequestMapping(method = RequestMethod.GET)的简化形式。下面的例子显示了一个MVC控制器,它被简化为一个组成@GetMapping注释。

public class AppointmentsController {

    private final AppointmentBook appointmentBook;

    public AppointmentsController(AppointmentBook appointmentBook) {
        this.appointmentBook = appointmentBook;

    public Map<String, Appointment> get() {
        return appointmentBook.getAppointmentsForToday();

7. @RequestScope, @SessionScope, @ApplicationScope Annotations

7.@RequestScope, @SessionScope, @ApplicationScope 注解

When using annotation-driven components or Java Config, the @RequestScope, @SessionScope and @ApplicationScope annotations can be used to assign a component to the required scope. These annotations not only set the scope of the bean but also set the scoped proxy mode to ScopedProxyMode.TARGET_CLASS.

当使用注解驱动的组件或Java Config时,@RequestScope@SessionScope@ApplicationScope注解可用于将组件分配到所需的范围。这些注解不仅可以设置Bean的作用域,还可以将作用域代理模式设置为ScopedProxyMode.TARGET_CLASS.

TARGET_CLASS mode means that CGLIB proxy will be used for proxying of this bean and ensuring that it can be injected in any other bean, even with a broader scope. TARGET_CLASS mode allows proxying not only for interfaces but classes too.

TARGET_CLASS模式意味着CGLIB代理将被用于代理这个Bean,并确保它可以被注入任何其他Bean中,甚至是更大的范围。TARGET_CLASS 模式不仅允许对接口进行代理,也允许对类进行代理.

public class LoginAction {
    // ...
public class UserPreferences {
    // ...
public class AppPreferences {
    // ...

8. @RequestAttribute and @SessionAttribute Annotations

8.@RequestAttribute@SessionAttribute 注释

Two more annotations for injecting parameters of the HTTP request into Controller methods appeared, namely @RequestAttribute and @SessionAttribute. They allow you to access some pre-existing attributes, managed globally (i.e. outside the Controller). The values for these attributes may be provided, for instance, by registered instances of javax.servlet.Filter or org.springframework.web.servlet.HandlerInterceptor.


Suppose we have registered the following HandlerInterceptor implementation that parses the request and adds login parameter to the session and another query parameter to a request:


public class ParamInterceptor extends HandlerInterceptorAdapter {

    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);


Such parameters may be injected into a Controller instance with corresponding annotations on method arguments:


public String get(@SessionAttribute String login, 
  @RequestAttribute String query) {
    return String.format("login = %s, query = %s", login, query);

9. Libraries/Application Servers Versions Support


Spring 4.3 supports the following library versions and server generations:

Spring 4.3支持以下库的版本和服务器世代。

  • Hibernate ORM 5.2 (still supporting 4.2/4.3 and 5.0/5.1 as well, with 3.6 deprecated now)
  • Jackson 2.8 (minimum raised to Jackson 2.6+ as of Spring 4.3)
  • OkHttp 3.x (still supporting OkHttp 2.x side by side)
  • Netty 4.1
  • Undertow 1.4
  • Tomcat 8.5.2 as well as 9.0 M6

Furthermore, Spring 4.3 embeds the updated ASM 5.1 and Objenesis 2.4 in spring-core.jar.

此外,Spring 4.3在spring-core.jar中嵌入了更新的ASM 5.1和Objenesis 2.4。

10. InjectionPoint


The InjectionPoint class is a new class introduced in Spring 4.3 which provides information about places where a particular bean gets injected, whether it is a method/constructor parameter or a field.

InjectionPoint类是Spring 4.3中引入的一个新类,它提供了关于特定Bean被注入的地方的信息,无论是方法/构造函数参数还是字段。

The types of information you can find using this class are:


  • Field object – you can obtain the point of injection wrapped as a Field object by using the getField() method if the bean is injected into a field
  • MethodParameter – you can call getMethodParameter() method to obtain the injection point wrapped as a MethodParameter object if the bean is injected into a parameter
  • Member – calling getMember() method will return the entity containing the injected bean wrapped into a Member object
  • Class<?> – obtain the declared type of the parameter or field where the bean in injected, using getDeclaredType()
  • Annotation[] – by using the getAnnotations() method, you can retrieve an array of Annotation objects which represent the annotations associated with the field or parameter
  • AnnotatedElement – call getAnnotatedElement() to get the injection point wrapped as an AnnotatedElement object

A case in which this class is very useful is when we want to create Logger beans based on the class to which they belong:


public Logger logger(InjectionPoint injectionPoint) {
    return Logger.getLogger(

The bean has to be defined with a prototype scope so that a different logger is created for each class. If you create a singleton bean and inject in multiple places, the Spring will return the first encountered injection point.

必须用prototype范围来定义Bean,以便为每个类创建不同的记录器。如果你创建了一个singleton bean并在多个地方注入,Spring将返回第一个遇到的注入点。

Then, we can inject the bean into our AppointmentsController:


private Logger logger;

11. Conclusion


In this article, we discussed some of the new features introduced with Spring 4.3.

在这篇文章中,我们讨论了Spring 4.3引入的一些新特性。

We’ve covered useful annotations that eliminate boilerplate, new helpful methods of dependency lookup and injection and several substantial improvements within the web and caching facilities.


You can find the source code for the article on GitHub.