Git Product home page Git Product logo

kouinject's People

Contributors

blurpy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

kouinject's Issues

Add support for injection in static members

Injection in static members is an optional feature of JSR-330, not implemented in KouInject yet.

The difficulty with injection in static members is to avoid injecting the same method more than once. KouInject is instance-oriented, meaning it only cares about the instance it creates there and then.

If multiple instances of a class are created (because of inheritance or scope) then any static method marked for injection will be injected for each instance.

To solve this, KouInject has to treat static members separately. Injection of all static members must be done in all beans before any of them are instantiated.

Also, some classes with static members may be pure utility classes with no instance members. Beans of those classes will probably never be injected in other beans, which means that the static members never gets injected.

Pure static classes should be used with care in the beans however, as the injector can't resolve the correct instantiation order without an instance being requested first.

Allow registration of alternative annotations for configuring the injector

Other dependency injection frameworks use different annotations for the same thing. Like how Spring uses the @Autowired annotation instead of @Inject (though Spring does support @Inject as well).

Often these annotations can work as direct replacements, since they are identical in use, but just have different names or lives in different packages.

To make porting of applications easier to KouInject, it should be possible to register alternative annotations for use by KouInject.

Example:

injector.registerInjectionAnnotation(org.springframework.beans.factory.annotation.Autowired.class); // Alternative to javax.inject.Inject.class
injector.registerProducesAnnotation(javax.enterprise.inject.Produces.class); // Alternative to net.usikkert.kouinject.annotation.Produces.class

Add support for JSR-299 factory methods with @Produces

Described here: http://docs.jboss.org/cdi/spec/1.0/html/implementation.html#producermethod

Must be simplified to work with the capabilities of JSR-330.

@Produces
public SomeBean createSomeBean() {
    SomeBean someBean = new SomeBeanImpl();
    ... // do extra initialization
    return someBean;
}

When an injection point requests an instance of SomeBean, then the factory method above will be used to create the instance. The factory method may define qualifiers, just like other beans. And the factory method may request injection of beans just like any method marked with @Inject.

Maybe support @Any like this:

@Produces @Any
public String getProperty(FactoryContext factoryContext) {
    String qualifier = factoryContext.getQualifier(); // could be settings.server.url
    ... // load correct property file
    return properties.getProperty(qualifier);
}

Used like this:

@Inject @Named("settings.server.url");
private String serverUrl;

FactoryContext could contain methods for getting the qualifier used, and the exact class wanted for injection. This way a factory could return different implementations based on those 2 parameters.

Scope must also be handled.

http://docs.jboss.org/weld/reference/1.0.0/en-US/html/beanscdi.html#d0e931
http://download.oracle.com/javaee/6/api/javax/enterprise/inject/Produces.html

Add support for ThreadScope

It may be useful to have separate bean instances in each thread.

This requires a new @Scope annotation, called @ThreadScoped.

It's important to note that a thread scoped bean may be injected in a bean in one thread, and used in several threads. There needs to be a different instance of the bean being used for each of the threads.

Example:

@Component
@ThreadScoped
public class ChildBean {

    public void beUseful() {
        System.out.println("I'm being useful");
    }
}

@Component
public class MotherBean {

    @Inject
    private ChildBean childBean;

    public void runThreads() {
        for (int i = 0; i < 10; i++) {
            new Thread() {
                public void run() {
                    childBean.beUseful();
                }
            }.start();
        }
    }
}

Every time a new thread runs childBean.beUseful() then a different instance of that bean must be instantiated and run.

For this to work, childBean must be a proxy with a reference to the ThreadScope, so it can request the correct bean from the scope on each method call. Should probably use cglib (http://cglib.sourceforge.net/) for this functionality.

Refactor ClassPathScanner

ClassPathScanner has way too much responsibility. Should be broken down into at least a directory scanner, and a jar scanner. And verify behavior both with Unix and Windows paths, with and without spaces in the path. Perhaps make ClassLoader selector separate as well.

Example of a jar URL in Linux:

jar:file:/home/christian/Utvikling/prosjekter/kouinject/target/test-classes/test-beans.jar!/net/usikkert/kouinject/testbeans/jar

The url is stripped to this before loading:
/home/christian/Utvikling/prosjekter/kouinject/target/test-classes/test-beans.jar

Example of a jar URL in Windows, with spaces:

jar:file:/C:/Users/Christian/Utvikling/kou%20inject/target/test-classes/test-beans.jar!/net/usikkert/kouinject/testbeans/jar

The url is stripped to this before loading:
C:/Users/Christian/Utvikling/kou inject/target/test-classes/test-beans.jar

Have to test how KouInject handles being loaded in a web application (.war) as well.

Add support for JSR-299 events with Event<T>

Described here: http://docs.jboss.org/cdi/spec/1.0/html/events.html

Must be simplified to work with the capabilities of JSR-330.

An event is sent like this:

@Inject
private Event<FunnyMessage> funnyMessageEvent;

public void sendFunnyMessageEvent() {
    FunnyMessage msg = new FunnyMessage("Laugh, now!");
    funnyMessageEvent.fire(msg);
}

The event is received like this:

public void receiveFunnyMessage(@Observeres FunnyMessage msg) {
    ... // Laugh at funny message
}

The message can be any class. No interfaces must be implemented. And qualifiers can be used just like any other injection.

Perhaps solved for prototype scoped beans using a WeakReference.

http://download.oracle.com/javase/6/docs/api/java/lang/ref/package-summary.html
http://www.kdgregory.com/index.php?page=java.refobj
http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html
http://stackoverflow.com/questions/299659/what-is-the-difference-between-a-soft-reference-and-a-weak-reference-in-java

Add a Java API for configuring beans, as an alternative to classpath scanning

The JSR-330 team originally wanted to define a low level API for configuring the injector. This API was never defined.

KouInject should add some kind of low level API, to be used by those who don't want to use classpath scanning. This API can be used directly, or as the base for creating other configuration methods, like xml-files.

This API should allow overriding automatic selection of which bean instance to inject.

Take the JSR-330 TCK as an example of how this feature can be used. The TCK specifies a SpareTire (extending Tire) with the qualifier "spare". The qualifier on the bean demands that the injection point also has the same qualifier to get an instance of that bean. @Inject @Spare Tire, or @Inject @Spare SpareTire are both valid. @Inject SpareTire is not valid, but KouInject has a hard-coded override to make sure that works, as the TCK tests for it.

The best way to handle this is to remove the hard-coded override in KouInject, and let the user define such overrides themselves.

The API would let me define these rules when running the TCK:

injectionPointOfClass(Tire.class).withQualifier("spare").injectsInstanceOf(SpareTire.class);
injectionPointOfClass(SpareTire.class).injectsInstanceOf(SpareTire.class);

Add support for Spring 3.1 @Profile

The @Profile annotation makes it easy to select one bean over another at runtime. It's almost like a qualifier, except qualifiers are set at compile time.

See http://blog.springsource.com/2011/02/14/spring-3-1-m1-introducing-profile/ for an example using Spring 3.1.

KouChat could be used as an example of where this would be useful, as KouChat has two different user interfaces. One made in Swing, and a pure console based one. The choice of which to use is detected at runtime from an application parameter.

Using @Profile, it could look like this:

public class KouChatMain() {

  public static void main(String[] args) {
    Injector injector = new DefaultInjector("swing");
    KouChat kouChat = injector.getBean(KouChat.class);
    kouChat.load();
  }
}

@Component
public class KouChat {

  @Inject
  private UserInterface userInterface;

  public void load() {
    userInterface.show();
  }
}

@Swing
@Component
public class SwingUserInterface implements UserInterface {

  public void show() {
    // Show Swing gui
  }
}

@Console
@Component
public class ConsoleUserInterface implements UserInterface {

  public void show() {
    // Show console gui
  }
}

@Swing and @Console are named profiles, based on the @Profile annotation.

We see that the injector is created with the string "swing" as input to the constructor. All the beans with the @Swing annotation and all the beans with no profile annotations will be available for injection. Those with other profile annotations, like @Console, will be ignored by the injector.

Some doc available at http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/ as well.

Add support for custom @Component

Two reasons.

  1. You get to annotate your beans with names that are more meaningful. Like @Model, @View, or @Controller.
  2. You can combine @Component and @Profile in one annotation. Perhaps if you have several beans in a profile that belong together. Like the @Swing annotation mentioned in the @Profile issue.

It could be defined like this:

@Component
@Profile
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Swing {

}

Add support for injecting collection of beans

Add support for injecting a collection of all the beans matching the generic argument. Must be able to inject all beans of a certain type even if they have different qualifiers.

@Inject
private Collection<Food> allFoodBeans;

Prototype beans gets instantiated too many times in v0.6

What steps will reproduce the problem?

  1. Create prototype Bean1 with sysout in constructor
  2. Create singleton Bean2 that injects Bean1 with sysout in constructor
  3. Get Bean2 from injector

What is the expected output?
Expect one sysout from each bean.

What do you see instead?
Get 2 sysout from Bean1, and 1 sysout from Bean2.

Add support for JSR-250 @PostConstruct and @PreDestroy

It may be useful to have better control of the lifecycle of beans. JSR-250 has been included in JavaSE 6.

@PostConstruct can be put an a single method in a bean, and should be called by the injector after all injections in that bean have been completed, but before the bean is available for use in other beans.

See http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/javax/annotation/PostConstruct.html

@PreDestroy can be put on a single method in a bean, and should be called by the injector before the bean is removed from scope. Prototype beans can not have this annotation, as the injector does not have control over them anymore after they are created.

See http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/javax/annotation/PreDestroy.html

Build fails with Java 7

Some tests fail when building with Java 7, because of a change in the way reflection on generic arrays are handled. In Java 6 a GenericArrayType is returned, but in Java 7 a Class is returned instead.

Tests that verify correct behavior when encountering generic arrays then fail.

Resources:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5041784
https://issues.apache.org/jira/browse/WINK-363
https://issues.jboss.org/browse/WELD-1132
http://weblogs.java.net/blog/kohsuke/archive/2008/12/introspecting_g.html

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.