Tutorial 1: Basic injection - wordandahalf/Blueprint GitHub Wiki
For this series of tutorials, we will be working with these two example classes:
package blueprintTest;
public class Foo {
private String fooText;
public Foo() {
this.fooText = "Hello, foo!";
}
public String getFoo() { return this.fooText; }
public void sayBar() { System.out.println("Hello, bar!"); }
}
and
package blueprintTest;
public class FooInjectior {
public static void main(String[] args) {
Foo myFoo = new Foo();
System.out.println(myFoo.getFoo());
myFoo.sayBar();
}
}
// When executed, this code will output:
// > Hello, foo!
// > Hello, bar!
In this tutorial, you will learn the simplest of injection using Blueprint: injecting code into a method. This is as simple as a few annotations and a method call.
The Blueprint annotation and the Blueprints class
Firstly, the class containing injection code must be decorated with
@Blueprint
. It has one parameter, target
, which should be set to the fully qualified name of the class which code should be injected into.
A few caveats: Blueprint currently does not support injecting into classes that have already been loaded, nor does it support injecting into JRE system classes.
@Blueprint
indicates to the BlueprintAnnotationProcessor
that this class contains injection logic. However, in order for the annotation processor to scan the class, you must add it to the queue via Blueprints#add
. The add
method has just one parameter, clazz
, the class which contains injection logic. In this case it is FooInjector.class
.
Next, to apply the loaded injection logic, you have to call Blueprints#apply
. This method cycles through the loaded injectors, applying them and finally loading the modified classes.
Thus, FooInjectior
now looks like this:
package blueprintTest;
@Blueprint(target = "blueprintTest.Foo")
public class FooInjectior {
public static void main(String[] args) {
Blueprints.add(FooInjectior.class);
Blueprints.apply();
...
That's all the setup you need! Next, we head into the world of injection with Blueprint!
The Inject annotation
@Inject
is the simplest, yet most complex of the various injection annotations. It has the parameters target
and at
.
target
: The case-sensitive name of the method to inject into.at
: The@At
which describes the location within the target method to inject into.
@At
has two parameters as well:
location
: The case-insensitive location in the method which to inject into. For this tutorial, we will be injecting at the first line of the method, which is indicated by using"HEAD"
for this parameter.args
: Any needed arguments for thelocation
used. The simple locations need not any arguments, so this may be omitted.
For more information on @At
, please see the wiki article on it.
For this tutorial, let's inject a Sysout
into the Foo#getFoo()
method. To do this, we need to add a new method into the FooInjector
class. Here are the rules for methods decorated with @Inject
:
- It must be a private and void method
- If the target method is an instance method, then the decorated method must also be an instance method. Likewise, if the target method is static, then the decorated method must also be static.
- It must have the same parameters as the target method
With these rules in mind, lets add a new method into our FooInjector
class:
package blueprintTest;
@Blueprint(target = "blueprintTest.Foo")
public class FooInjectior {
...
@Inject(target = "getFoo", at = @At(location = "HEAD"))
private void getFoo() {
System.out.println("Hello, from injection!");
}
}
With this method added, if you were to run this code now, you would get the following output:
> Hello, from injection!
> Hello, foo!
> Hello, bar!
Congratulations! You now can use basic injection using Blueprint! There are several other tutorials to continue with, the next of which should be Tutorial #2