Codelytics

Visualise your geek speak

  • Blog
  • Terms
  • Privacy
  • Contact

Constructor & Setter Dependency Injection

September 1, 2018 by Adrian Bartlett Leave a Comment

If you were asked in an interview: “What types of bean injection are there in Spring”. What would your answer be?

There are two types of bean injection in Spring: Setter-based dependency injection (DI) and Constructor-based dependency injection…

Best Practice

If you were asked: “When should you use constructor based DI and when should you use setter based DI?” A good answer would be:

Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies.

Proxy & Non-proxy Dependency Injection

At this point the interviewer is thinking, hey this developer is good, now lets really test him: “Tell me what other types of Bean Injection there are, I will give you a hint: the Transactional annotation”.

If you’re not sure on this answer, read on to see how Spring handles these types of annotations.

Example

If classes or methods are annotated with certain annotations like @Transactional, a proxy is injected by Spring to add extra functionality. Take a look at the following code:

    @Controller
    public class MainController {

        @Autowired
        private FooService fooService;

        @GetMapping("/")
        public String main(Model model) {
            fooService.findAll();
            //...
        }
    }

    @Service
    @Transactional
    public class FooService {

        @Autowired
        private IFooDao dao;

        public List findAll() {
            return dao.findAll();
        }
    }

    @Repository
    public class FooDao extends AbstractJpaDAO implements IFooDao {
        //...
    }

Analysing the code, the following call sequence takes place:

MainController::main() → FooService::findAll() → AbstractJpaDAO::findAll()

However is this what happens at runtime?

Class Diagram


The class diagram above shows what happens at runtime. The following call sequence is actual what takes place:

MainController::main() → FooService$$EnhancerBySpringCGLIB$$3c710fca::findAll() → TransactionInterceptor::invoke() → FooService::findAll() → AbstractJpaDAO::findAll()

Notice how this is different to the call sequence shown above. When Spring sees the @Transactional annotation on FooService (see line 15 in code sample):

  • It creates a proxy for FooService called FooService$$EnhancerBySpringCGLIB$$3c710fca
  • The proxy is created as a subclass of FooService. Note the ⇾ relationship
  • This proxy is responsible for using the TransactionInterceptor to inject transaction functionality, around the FooService::findAll call
  • Spring then injects this proxy into MainController. In the Class Diagram notice how the call goes from FooService directly to AbstractJpaDAO (FooDao’s super class). Spring hasn’t injected a proxy here because the @Repository annotation doesn’t require a proxy.

Sequence Diagram


Read through the sequence diagram above, to see how Spring has injected @Transactional behaviour.

What other Annotations cause Spring to inject a proxy? Let us know in the comments.

Share this:

  • Click to email this to a friend (Opens in new window)
  • Click to print (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • Click to share on Twitter (Opens in new window)
  • Click to share on Google+ (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)

Filed Under: Blog posts, Java, JPA, Spring Tagged With: Java, Spring

Connect with us

  • Facebook
  • Google+
  • Twitter
  • YouTube

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • Facebook
  • Google+
  • Twitter
  • YouTube

Subscribe to the blog

Recent posts

  • LinkedHashMap Tutorial
  • java.util.TreeMap visualized: interactive view from a new perspective
  • Constructor & Setter Dependency Injection
  • 4 Reasons to use a Java Semaphore
  • Java 8: How To Retrieve Absent Values From HashMap

Search

  • Blog
  • Terms
  • Privacy
  • Contact

All website content, including software, (excluding that owned by Wordpress and Centric Theme on Genesis Framework) is owned by Codelytics Pty Ltd and/or its affiliates, all rights reserved and protected by Australian copyright laws and relevant international treaty provisions. Any reproduction, redistribution and/or reverse engineering is expressly prohibited. For further details see the terms and conditions page on this site.
© Codelytics Pty Ltd, Adrian Bartlett, 2013

Copyright © 2022 · Centric Theme on Genesis Framework · WordPress · Log in

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.