扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
public class CalculatorMDB implements MessageListener {
@EJB Calculator cal;
// Use the cal variable
// ... ...
}
注释如果被用在JavaBean风格的setter方法上时,容器会在属性第一次使用之前,自动地用正确的参数调用bean的setter方法。下面的片断演示了这是如何做的:
public class CalculatorMDB implements MessageListener {
Calculator cal;
@EJB
public void setCal (Calculator cal) {
this.cal = cal;
}
// Use the cal variable
// 使用cal变量
// ... ...
}
除@EJB注释之外,EJB 3.0也支持@Resource注释来注入来自JNDI的任何资源。下面的例子中,我演示了如何注入服务器端默入的TimerService和SessionContext对象,也演示了如何注入来自JNDI的命名数据库和JMS资源。
@Resource
TimerService tms;
@Resource
SessionContext ctx;
@Resource (name="DefaultDS")
DataSource myDb;
@Resource (name="ConnectionFactory")
QueueConnectionFactory factory;
@Resource (name="queue/A")
Queue queue;
此外,你也可以把一个容器管理的持久化管理器(也就是,EntityManager-类似于Hibernate session对象)注入到EJB 3.0 POJO中。
把容器服务交给POJO
除了管理生命周期和访问藕合松散的服务对象外,EJB 3.0通过简单的注释也为POJO提供了运行时刻服务。
事务
最有用的容器服务可能就是事务管理服务,当应用出现失败或异常时,它保证了数据库的完整性。你可以简单地将为一个POJO方法申明它的事务属性。这样容器就可以在合适的上下文中运行这个方法。举例来说,下面的代码申明了容器在运行updateExchangeRate()时必须创建一个新的事务。当这个方法退出时提交事务。实际上,所有在updateExchangeRate()中被调用的方法都在此事务中运行,除非有特别申明。在updateExchangeRate()中的数据库操作要么全部成功,要么全部失败。
@Stateless
public class CalculatorBean implements Calculator {
// ... ...
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void updateExchangeRate (double newrate) throws Exception {
// Update the database in a loop.
// 在循环中更新数据库
// ... ...
// The operations in the loop must all be successful or
// the database is not updated at all.
// 循环中的操作必须全部成功或者根本不更新。
}
}
安全
容器也提供了安全服务来进行用户认证和根据用户规则来限制对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 <Fund> getFunds () {
// ... ...
}
// ... ...
@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");
}
}
}
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者