安全
容器也提供了安全服务来进行用户认证和根据用户规则来限制对POJO的访问。对每一个POJO来说,你可以通过使用 @SecurityDomain注释为它指定一个安全域, 安全域告诉容器到哪里去找密码和用户角色列表。JBoss中的other域表明文件是classpath中的users.propertes和 roles.properties。这样,对每一个方法来说,我们可以使用一个安全限制注释来指定谁可以运行这个方法。比如,下面的例子,容器对所有试图调用addFund()的用户进行认证,只允许拥有AdminUser角色的用户实际运行它。如果你没有登录或者没有以管理员的身份登录,一个安全意外将会抛出。
@Stateless
@SecurityDomain("other")
public class CalculatorBean implements Calculator {
@RolesAllowed({"AdminUser"})
public void addFund (String name, double growthrate) {
// ... ...
}
@RolesAllowed({"AdminUser"})
public void addInvestor (String name, int start, int end) {
// ... ...
}
@PermitAll
public Collection
// ... ...
}
// ... ...
@RolesAllowed({"RegularUser"})
public double calculate (int fundId, int investorId,
double saving) {
// ... ...
}
}
通用拦截器
事务和安全服务都可以被看作是容器管理的运行时刻拦截器。容器拦截了对EJB存根的调用,并在其上应用事务上下文或进行安全限制。
在EJB 3.0中,你可以自己写拦截器来扩展容器服务。使用@AroundInvoke注释,你可以将任意bean方法作为拦截器方法在任意bean方法之前和之后运行。下面的例子中,log()方法是一个拦截器,它计算和记录了其它bean方法的执行时间:
@Stateful
public class CalculatorBean implements Calculator {
// Bean methods that are to be intercepted by "log()"
// bean方法将被log()方法拦截
//
// ... ...
@AroundInvoke
public Object log (InvocationContext ctx)
throws Exception {
String className = ctx.getBean().getClass().getName();
String methodName = ctx.getMethod().getName();
String target = className + "." + methodName + "()";
long start = System.currentTimeMillis();
System.out.println ("Invoking " + target);
try {
return ctx.proceed();
} catch(Exception e) {
throw e;
} finally {
System.out.println("Exiting " + target);
cal.setTrace(cal.getTrace() + "
" +
"Exiting " + target);
long time = System.currentTimeMillis() - start;
System.out.println("This method takes " +
time + "ms to execute");
}
}
}
下一步?
在第一部分中,我大致地讨论了EJB 3.0基于POJO的编程模型和如何在EJB 3.0中开发藕合松散的服务组件。在第二部分中,我会讨论EJB 3.0的另一个主要的概念:可管理的POJO持久性。
