开发者

How Dependency Injection Manually Implemented?

How we can 开发者_如何学Cmanually inject an object without using the facility of containers. I did something similar through reflection as follows.

Class actionClass = Class.forName("SampleClass");
Object actionObject = actionClass.newInstance();
Method reqMethod = actionClass.getMethod("setRequest", HttpServletRequest.class);
reqMethod.invoke(actionObject,request);

is it the right way to do DI?

My intention is to pass request object to different controller classes dynamically from a dispatcher filter,where we get request and response objects. I am fearing about the performace of reflection.Is there any replacement for doing DI?


Dependency injection is nothing more than providing a class with its dependencies, rather than have it find them itself (via singletons/lookups etc.). So you can do it in code trivially thus:

DatabaseConnection dc = new DatabaseConnection();
MyDAO dao = new MyDAO(dc);

(pseudocode). Here the MyDAO is being injected with a database connection. If that database connection implements an interface you can easily mock this out during testing.


Well, when you set one object into another object using setter method or through a constructor it also is the dependency injection. Dependency injection only means creating relationship(dependency) in objects.

Using reflection as you did is just another form of it.


Why would you use reflection? Why not simply:

SampleClass action = new SampleClass();
action.setRequest(request);

That does the same thing, but is more readable, allows the compiler to check that the types and methods actually exist, provides you with Javadoc for the Method invoked, enables your IDE to assist in refactorings, ...

And it still is dependency injection, because the action doesn't go looking for its request, but receives the request during initialization.

Edit: Thorbjørn requested I show how that action would be used. It would itself be injected (using a setter) into whatever component uses the action. The component would then use the injected action object.

SampleClass action = new SampleClass();
action.setRequest(request);
Servlet servlet = new ActionBasedServlet();
servlet.setAction(action);

If servlet is intended to live longer than action, i.e. it should use a fresh Action each time it needs one, one can instead setter-inject an ActionFactory into servlet.

In this concrete case, I'd question whether the action really needs to keep a request as part of its state, or can be immutable and simply act on the request passed by the Servlet as method parameter. In that case, the boot-time initialization would do:

SampleClass action = new SampleClass();
Servlet servlet = new ActionBasedServlet();
servlet.setAction(action);

and ActionBasedServlet would define

public void serve(Request req, Response resp) {
    foo();
    action.act(req, resp);
    bar();
}


Dependency Injection implies you get properly initialized references appearing "by magic".

You call the setRequest() method with the request object, but DI frequently also allows for setting the fields without invoking methods.

Guice does not as such require a container, but uses class loader magic started in the main method. Would that be useable for you?


Spring framework is one of the most popular DI implementations. It is also opensource. You can check out the class org.springframeowrk.beans.BeanUtils, specifically the methods copyProperties (all 4 of them) for examples on how to do this. For more info you can also see the class hierarchy of org.springframework.beans.factory.BeanFactory for different strategies.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜