SeamFramework.orgCommunity Documentation

Chapter 11. Unwrapping Producer Methods

Unwrapping producer methods allow you to create injectable objects that have "self-managed"" lifecycles, and are particularly useful if you have need a bean whose lifecycle does not exactly match one of the lifecycle of one of the existing scopes. The lifecycle of the bean is are managed by the bean that defines the producer method, and changes to the unwrapped object are immediately visible to all clients.

You can declare a method to be an unwrapping producer method by annotating it @Unwraps. The return type of the managed producer must be proxyable (see Section 5.4.1 of the CDI specification, "Unproxyable bean types"). Every time a method is called on unwrapped object the invocation is forwarded to the result of calling the unwrapping producer method.

For example consider a permission manager (that manages the current permission), and a security manager (that checks the current permission level). Any changes to permission in the permission manager are immediately visible to the security manager.

@SessionScoped

class PermissionManager {
   
   Permission permission;
  
   void setPermission(Permission permission) {
      this.permission=permission;
   }
  
   @Unwraps @Current
   Permission getPermission() {
      return this.permission;
   }
}
class SecurityManager {

   
   @Inject @Current
   Permission permission;
  
   boolean checkAdminPermission() {
      return permission.getName().equals("admin");
   }
}

When permission.getName() is called, the unwrapped Permission forwards the invocation of getName() to the result of calling PermissionManager.getPermission().

For example you could raise the permission level before performing a sensitive operation, and then lower it again afterwards:

public class SomeSensitiveOperation {

   
   @Inject
   PermissionManager permissionManager;
  
   public void perform() {
      try {
         permissionManager.setPermission(Permissions.ADMIN);
         // Do some sensitive operation
      } finally {
         permissionManager.setPermission(Permissions.USER);
      }
   }
}

Unwrapping producer methods can have parameters injected, including InjectionPoint (which repreents) the calling method.