One of the really nice things about Weld is how nicely it works in Java SE. Of course, if you run Weld on its own, you won't get nice functionality like EJBs (you'll need an embeddable EJB container for that), but you do get a bunch of great stuff, including:
- Managed beans with @PostConstruct and @PreDestroy lifecycle callbacks
- Dependency injection with qualifiers and alternatives
- @ApplicationScoped, @Dependent and @Singleton scopes
- Interceptors and decorators
- Stereotypes
- Events
- Portable extension support
The Weld distribution comes with an example console application, and an example Swing application.
Here's a very simple console application:
@Singleton
public class HelloWorld {
@PostConstruct
void init() {
System.out.println("Initializing Hello World application");
}
void printHello(@Observes ContainerInitialized event,
@Parameters List<String> parameters) {
System.out.println("Hello " + parameters.get(0));
}
}
The printHello() method is a CDI observer method for the ContainerInitialized event. This event is fired by the Weld Java SE extension when the console application starts. The command line parameters are available for injection using @Parameters List<String>.
As usual, we need a file named META-INF/beans.xml the the jar or classpath directory containing our HelloWorld class.
We run the application using:
java org.jboss.weld.environments.se.StartMain Gavin
Of course, if you're using CDI you probably want to make much more use of dependency injection, for example:
@Singleton
public class HelloWorld {
void printHello(@Observes ContainerInitialized event,
@Parameters List<String> parameters,
Hello hello) {
hello.say(parameters.get(0));
}
}
Where Hello is a bean:
public class Hello {
public void say(String name) {
System.out.println("Hello " + name);
}
}
The Weld SE extension was created by contributor Peter Royle.
Shouldn't you use @Inject annotation to inject Hello bean into printHello() or @Observes for the event parameter is enough to injection for the other parameters?
@Observes is enough.
A interesting extension to Weld SE is Weld Test. Unreleased as of now, but soon..
It gives you CDI/Weld injection in your test cases. The JUnit version also supports method argument injection.
package org.jboss.weld.test.junit; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(CDIRunner.class) public class ModelTestCase { @Language(LanguageType.NO) private WelcomeService service; @Test public void shouldBeAbleToInjectInstanceVars() throws Exception { Assert.assertEquals("Hei " + userName, service.greet(user)); } @Test public void shouldBeAbleToInjectParameters(@Language(LanguageType.SE) WelcomeService welcomeService) throws Exception { Assert.assertEquals("Hej " + userName, welcomeService.greet(user)); } }If you want to test it, it can be found at: svn
Nice, Aslak. I like it.
Hi. Is it possible to extends all java.awt. and javax.swing. UI component to run well with weld? I know there is JSR 296 to satisfy this, but I think the JSR is not transparent enough.
I'm not sure what you mean by . You're thinking of databinding? That's a problem that needs to be solved in Swing, I guess...
Hmm, since I have try seam in my last project, I have some idea to swing like:
@UI("main") public class Main extends JFrame { JMenuItem menuLogin; JMenuItem menuLogout; public MainFrame() { // init component.. } } @Controller public MainApplicationController { @Inject Main main; @Inject AccountingFrame accountingFrame; @UIEvent(for="menuLogin", at="main") public void login() { if (validate()) { acountingframe.show(); // other logic after login } } @UIEvent(for="menuLogout", at="main") public void logout() { mainapps.dispose(); // Other logic for logout.. } } // etc etc..I dont know whether this is a good idea, since I know nothing in deep about Weld (Just seam with its seam gen :D ) and just newbie in DI world, but I think I can archive more clarity with this way.
How do you thing?
And, yes, databinding in swing also need an encachement.
Upps.. Sorry, typo. What should I write is
Looks untypesafe. The usual swing approach of registering event listeners has the advantage of being typesafe...
The testing stuff does look nice. Is it easy to integrate with TestNG? Probably just a @BeforeClass or something? Also what do the @Language annotations do?
Weld Test supports both JUnit and TestNG.
The @Language annotation is just a CDI annotation used as a example.. :)
Would be great to have sample JUnit base class for test cases that use weld. Like spring test base classes that are injected as well. There was a reference to svn but it seems to be broken?
Hi. Test SVN Url is no longer existing.