Help

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Here is a very simple design pattern example based on the @Unwrap, @Create, and @Startup Seam annotations in the context of the manager component pattern.

Definition: A manager component is any component with an @Unwrap method. This method returns the value that will be visable to clients, and is called every time a context variable is referenced.

source: Seam 2.1.2 ref doc, pg. 124

Whereas the factory component pattern (use @Factory) returns a value when the context variable is referenced but is null, the manager component pattern returns a value every time the context variable is referenced.

In this specific use case, we want the init() method in TestUnwrapAction to be executed when the application is deployed in the app server. This happens via the @Startup and @Create annotations. Remember that the only two permissible scopes for your component when using @Startup are @Application or @Session. Prior to init() being executed, the appSiteList context variable is injected because whenever appSiteList is referenced, the @Unwrap method getAppSiteList() is executed. In Seam, injections always occur prior to any business method execution. Prior to the @Unwrap method executing, the @Create method for TestAppSiteList executes.

So basically our populated List<ApplicationSite> from TestAppSiteList is available in the init() method of TestUnwrapAction for iteration and processing.

TestUnwrapAction.java:

@Name("unwrapAction")
@Startup
@Scope(ScopeType.APPLICATION)
public class TestUnwrapAction {
	
	@Logger
	private Log log;
	
	@In
	protected List<ApplicationSite> appSiteList; //manager component
	
	@Create
	public void init(){
		for(ApplicationSite as : appSiteList){  //exec 3rd
			log.info("as.getAddedDate() = "+as.getAddedDate());
		}
	}
	
}

TestAppSiteList.java:

@Name("appSiteList")
@AutoCreate
public class TestAppSiteList {

	@In
	private EntityManager entityManager;
	
	private List<ApplicationSite> list;
	
	@Create
	public void init(){
		list = entityManager.createQuery("from ApplicationSite").getResultList();   //exec first
	}
	
	@Unwrap
	public List<ApplicationSite> getAppSiteList() {
		return list;  //exec second
	}
}

Also, note the use of @AutoCreate in TestAppSiteList. This saves us from having to type @In(create=true) and instead we use @In for injection. This can save a lot of typing if a component is injected into many different components.

Be aware of a bad practice (danger!) in using the manager component pattern. Do not execute db operations via EntityManager or Session interfaces (or even JDBC, etc.) or any other heavy performance hitting operations in the @Unwrap method. This method is executed every time the context variable (i.e. the component name like 'appSiteList' in the example above) is referenced. So if you have a db operation in the @Unwrap method, you may experience performance degradation.