Guice Framework-DI (Dependency Injection Property Injection)

1.2.1 Basic property injection

Let's look at an example first. Service.java

 @ImplementedBy(ServiceImpl.class)

  public interface Service {

      void execute();

 }

 

ServiceImpl.java

 public class ServiceImpl implements Service {

    @Override

    public void execute() {

        System.out.println("This is made by Teny (www.teny32.blog.51cto.com).");

    }

}

FieldInjectDemo.java

 5 public class FieldInjectDemo {

 6     @Inject

 7     private Service servcie;

 8     public Service getServcie() {

 9         return servcie;

10     }

11     public static void main(String[] args) {

12         FieldInjectDemo demo = Guice.createInjector().getInstance(FieldInjectDemo.class);

13         demo.getServcie().execute();

14     }

15 }

This example is relatively simple. Specifically, the interface Service is injected into the FieldInjectDemo class through the @Inject annotation, and then the service is used in the FieldInjectDemo class. Of course, the Service service has been associated with the ServiceImpl class through the @ImplementedBy annotation, and a new instance (non-singleton) is generated each time. Note that the FieldInjectDemo class here is not associated with Guice through Module, etc. For details, see "".

As expected, we got the result we expected.

 

Similarly, we deepen our understanding by asking questions (note that we only emphasize how to use it in the introductory tutorial, and we will talk about the principles and underlying ideas in the advanced tutorial).

Question (1): Can I construct the FieldInjectDemo object myself without going through Guice?

 1 /** field inject demo2

 2 * @author Teny (www.teny32.blog.51cto.com)

 3  * @version $Rev: 73 $

 4  */

 5 public class FieldInjectDemo2 {

 6     @Inject

 7     private Service servcie;

 8     public Service getServcie() {

 9         return servcie;

10     }

11     public static void main(String[] args) {

12         FieldInjectDemo2 fd = new FieldInjectDemo2();

13         fd.getServcie().execute();

14     }

15 }

Like in the example above, then run it and see? Unfortunately, we got a result that no one liked.

Exception in thread "main" java.lang.NullPointerException

    at cn.imxylz.study.guice.inject.FieldInjectDemo2.main(FieldInjectDemo2.java:22)

Obviously, since FieldInjectDemo2 is not hosted by the Guice container (let's call it a container for now), the Service service has no chance to be injected into the FieldInjectDemo2 class.

 

Question (2): Can static properties be injected?

 

See the code below.

 1 public class FieldInjectDemo2 {

 2     @Inject

 3     private static Service servcie;

 4     public static Service getServcie() {

 5         return servcie;

 6     }

 7     public static void main(String[] args) {

 8         FieldInjectDemo2 fd = Guice.createInjector().getInstance(FieldInjectDemo2.class);

 9         FieldInjectDemo2.getServcie().execute();

10     }

11 }

Unfortunately! The results tell us that Guice doesn't seem to support static field injection yet.

Well, let's put the above two problems aside for now, and we will continue to learn other injection functions.

1.2.2 Constructor Inject

Continue to look at the example. Examples are a great way to illustrate a problem.

 1     /**

 2      * $Id: ConstructorInjectDemo.java 75 2009-12-23 14:22:35Z xylz $

 3      * xylz study project (www.teny32.blog.51cto.com)

 4      */

 5     package cn.imxylz.study.guice.inject;

 6 

 7     import com.google.inject.Guice;

 8     import com.google.inject.Inject;

 9 

10     /** a demo with constructor inject

11 * @author Teny (www.teny32.blog.51cto.com)

12      * @version $Rev: 75 $

13      */

14     public class ConstructorInjectDemo {

15 

16         private Service service;

17         @Inject

18         public ConstructorInjectDemo(Service service) {

19             this.service=service;

20         }

21         public Service getService() {

22             return service;

23         }

24         public static void main(String[] args) {

25             ConstructorInjectDemo cid = Guice.createInjector().getInstance(ConstructorInjectDemo.class);

26             cid.getService().execute();

27         }

28 

29     }

30 

31 

We add @Inject to the constructor to achieve the purpose of automatic injection. The benefit of constructor injection is that there is only one place to do property injection, which ensures that some initialization work is done in the constructor (although this is not recommended). Of course, the disadvantage of constructor injection is that the instantiation of the class is bound to the parameters, which limits the way to instantiate the class.

 

Question (3): Can multiple parameters be automatically injected into the constructor?

 1     public class ConstructorInjectDemo {

 3         private Service service;

 4         private HelloWorld helloWorld;

 5         @Inject

 6         public ConstructorInjectDemo(Service service,HelloWorld helloWorld) {

 7             this.service=service;

 8             this.helloWorld=helloWorld;

 9         }

10         public Service getService() {

11             return service;

12         }

13         public HelloWorld getHelloWorld() {

14             return helloWorld;

15         }

16         public static void main(String[] args) {

17             ConstructorInjectDemo cid = Guice.createInjector().getInstance(ConstructorInjectDemo.class);

18             cid.getService().execute();

19             System.out.println(cid.getHelloWorld().sayHello());

20         }

21     }

22 

23 

Perfectly supports multi-parameter constructor injection. Of course, there is no need to write multiple @Injects, and if they are written, they cannot be compiled.

1.2.3 Setter ((Setter Method Inject)

With the above foundation, it is very simple to look at Setter injection, just add an @Inject annotation to the setter method.

 

 

 1     public class SetterInjectDemo {

 2 

 3         private Service service;

 4 

 5         @Inject

 6         public void setService(Service service) {

 7             this.service = service;

 8         }

 9 

10         public Service getService() {

11             return service;

12         }

13 

14         public static void main(String[] args) {

15             SetterInjectDemo sid = Guice.createInjector().getInstance(SetterInjectDemo.class);

16             sid.getService().execute();

17         }

18 

19     }

20 

Well, let's go back to the static injection of question 2. The following example demonstrates how to inject a static field.

 

 1     /** a demo for static field inject

 2 * @author Teny (www.teny32.blog.51cto.com)

 3      * @version $Rev: 78 $

 4      */

 5     public class StaticFieldInjectDemo {

 6 

 7         @Inject

 8         private static Service service;

 9 

10         public static void main(String[] args) {

11             Guice.createInjector(new Module() {

12                 @Override

13                 public void configure(Binder binder) {

14                     binder.requestStaticInjection(StaticFieldInjectDemo.class);

15                 }

16             });

17             StaticFieldInjectDemo.service.execute();

18         }

19     }

20 

21 

Excellent! Above we did not use Guice to get a StaticFieldInjectDemo instance (nonsense), in fact static fields (properties) are class-related, so we need to request static injection services. But one benefit is that from the outside it looks like our service has no Guice bindings, and even the client doesn't know (or doesn't care) about the service's injection process.

 

Going back to question (1), referring to the process of static injection above, we can use the following methods to inject properties of instance variables.

 

 

 1     public class InstanceFieldInjectDemo {

 2 

 3         @Inject

 4         private Service service;

 5         public static void main(String[] args) {

 6            final InstanceFieldInjectDemo ifid = new InstanceFieldInjectDemo();

 7             Guice.createInjector(new Module() {

 8                 @Override

 9                 public void configure(Binder binder) {

10                     binder.requestInjection(ifid);

11                 }

12             });

13             ifid.service.execute();

14         }

15     }

16 

17 

Actually there is an easy way to inject fields, in fact this method also supports Setter injection.

 

 

 1     public class InstanceFieldInjectDemo {

 2 

 3         @Inject

 4         private Service service;

 5         public static void main(String[] args) {

 6             InstanceFieldInjectDemo ifid = new InstanceFieldInjectDemo();

 7             Guice.createInjector().injectMembers(ifid);

 8             ifid.service.execute();

 9         }

10     }

11 

12

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327013745&siteId=291194637