BE Study 4th

 Aren't you curious that 

    public CategoryService(CategoryRepository categoryRepository) {
        this.categoryRepository = categoryRepository;
    }
code like this is possible? CategoryRepository is just an interface, not a class and how could they declare categoryRepository?
I figured out what this makes possible is 'Dynamic Proxy' of Spring.

To know it, you should know what 'Proxy' is first.
Proxy is a type of design pattern. 
Proxy has an architecture like below.




Then what is proxy for?
Advantages of proxy pattern are
1. adding additional features without longing the existing class.
2. manage access rights. Using proxy makes the client cannot access the target(the real feature the client needs)

So the code will consist of

1. TargetInterface.java : Parent Interface of proxy and TargetImplement. 
2. TargetImplement.java : Code that conducts the actual action of the target.
3. Proxy.java : the code that calls TargetImplement instead of the client. While calling TargetImplement, it can do some additional features.

and the main would look like

TargetInterface target = new TargetImplement();
TargetInterface proxy = new Proxy(target);
Client client = new Client(proxy);
client.execute();

So when client.execute -> proxy.run -> TargetImplement.run 

And in my opinion, I think this is not just proxy pattern, but proxy + Dependency Injection. There would be no reason to separate TargetInterface for the 'proxy' reasons.

Then what is Dependency Injection? How do you inject dependency? Let's look into the code.

@Service
public class UserService {

    private UserRepository userRepository;
    private MemberService memberService;

    @Autowired
    public UserService(UserRepository userRepository, MemberService memberService) {
        this.userRepository = userRepository;
        this.memberService = memberService;
    }
    
}

This is the most basic, and also recommended way of DI: Constructor Injection. There's some other ways of DI like 

@Service
public class UserService {

    private UserRepository userRepository;
    private MemberService memberService;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Autowired
    public void setMemberService(MemberService memberService) {
        this.memberService = memberService;
    }
}

The above is called Setter Injection. We cannot notice anything special. It's just member variables userRepository or memberService is used as a parameter for methods like constructor or setter. 
The point lies in the fact that the userRepository and memberService is defined as not a class but an interface. Spring discourages to use classes as parameters because it makes dependency fixed. Instead, it encourages to set parameters and return types as interfaces, so that it can be open for extension.
Actual construction of objects(instances) are up to the framework.

댓글

이 블로그의 인기 게시물

Interface of Java

Data Analytics Overview(OLTP vs OLAP)

Leetcode