JavaEE5学习笔记05-EJB之会话Bean(sessionBean)总结-----7
就像Spring IOC所倡导的那样(其实是Spring设计时借鉴的EJB的思想),当一个Bean完成一项任务的时候需要其他的组件配合使用才能完成,这个时候就出现了依赖,此Bean依赖于另一个Bean的某些服务才能完成自己的服务。那么我们最原始的办法就是new一个Bean出来是吧?当然这是十分,不太成熟的做法。在《Effective Java》这本书中第一章节就提倡类和类之间调用不要用new,构造函数也尽量用工厂去创建等等……总之依赖注入就是为了解耦。在JBoss这种应用服务器中的EJB容器组件如果需要互相调用该怎么办呢,同样为了不硬编码、解耦合。就需要容器注入了。我们来看例子
接口1
?
@Local
public interface XMLUtilBean {
??? public String readXml();
}
实现类1
?
?
?
@Stateless?
public class XMLUtilBeanEAOImpl implements XMLUtilBean {
???
??? @Override
??? public String readXml() {
?????? return "xml服务…………";
??? }
}
接口2
?
?
?
@Remote?
public interface ServerBean {
??? public boolean insert(String name);
}
实现类2
?
@Stateless
public class ServerBeanEAOImpl implements ServerBean {
?
??? @EJB(beanName = "XMLUtilBeanEAOImpl")
??? private XMLUtilBean xMLUtilBean;
?
??? @Override
??? public boolean insert(String name) {
?????? String xml = xMLUtilBean.readXml();
?????? System.out.println(xml + "::::" + name);
?????? return true;
??? }
}
此处实现类用了@EJB(beanName = "XMLUtilBeanEAOImpl")注解将EJB组件名为XMLUtilBeanEAOImpl的组件给注入了进来。所以在insert方法中可以直接调用xMLUtilBean对象了。
测试代码如下:
?
??? public void test01() throws Exception {
?????? Context context = init();
?????? ServerBean serverBean = (ServerBean) context
????????????? .lookup("ServerBeanEAOImpl/remote");
?????? System.out.println(serverBean.insert("蜕变妖狼"));
??? }
执行后JBoss控制台信息如下:
?
16:04:19,450 INFO? [STDOUT] xml服务…………::::蜕变妖狼
证明被注入的组件使用正常。
以上是EJB组件之间的调用可以使用@EJB注解作为依赖注入,如果该EJB使用了容器的某些类,比如应用上下文对象、数据源等等,其实大可不必手工创建这些资源,在EJB中直接采用资源注入就可以了。如下代码
?
@Stateless@TransactionManagement(TransactionManagementType.CONTAINER)
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class ResourceDIServerBeanEAOImpl implements ResourceDIServerBean {
?
??? @Resource(mappedName="java:/jbossdemo")
??? private DataSource dataSource;
?
??? @Resource
??? private SessionContext sessionContext;
?
??? @Override
??? public void insert() {
?????? Connection connection = null;
?????? Statement statement = null;
?????? try {
?????????? connection = dataSource.getConnection();
?????????? statement = connection.createStatement();
?????????? String insert1 = "insert into person values(9,'剑藏玄')";
?????????? String insert2 = "insert into person values(10,'傲笑红尘')";
?????????? statement.executeUpdate(insert1);
?????????? statement.executeUpdate(insert2);
?????????? statement.close();
?????????? connection.close();
?????? } catch (Exception e) {
?????????? System.out.println("事务回滚~~");
?????????? sessionContext.setRollbackOnly();
?????????? e.printStackTrace();
?????? }
??? }
}
在这个会话Bean中就注入了数据源和容器会话上下文。这样开发者就省去了自己实例化的步骤,直接引用容器给你注入的资源就好了。
类似于Spring集成了Quartz似的,EJB自己有一个任务调度管理器。也可以指定某个时间执行某些特殊的任务,比如在晚上0点的时候银行清点所有分行的账务、统计局在每个月的月底集中统计某些“和谐”后的统计数字等等……下面我们看简单实用例子
接口
?
@Remote
public interface ITimeEAO {
??? void setTimeServer(Date date, long timeLong);
??? void gc(Timer timer);
}
实现类如下
?
?
?
?@Statelesspublic class TimeEAOImpl implements ITimeEAO {
?
??? @Resource
??? TimerService timerService;
?
??? /**
??? ?* 实际执行的方法
??? ?*
??? ?* @Timeout就是定义执行的方法
??? ?*/
??? @Override
??? @Timeout
??? public void gc(Timer timer) {
?????? // TODO Auto-generated method stub
?????? System.out.println("timer.getInfo():" + timer.getInfo());
?????? System.out.println("建议服务器赶紧进行垃圾回收");
?????? System.gc();
??? }
?
??? /**
??? ?* 对于定时器的一些设置
??? ?*/
??? @Override
??? public void setTimeServer(Date date, long timeLong) {
?????? /**
?????? ?* 每隔timeLong时间就执行一次gc方法
?????? ?*/
?????? timerService.createTimer(date, timeLong,"执行任务");
??? }
?
}
如果调用timerService.createTimer(date, timeLong)那么只执行一次。还有就是注意timeLong单位是秒。测试代码如下
?
??? public void test01() throws NamingException {
?????? context = init();
?????? ITimeEAO imeEAO = (ITimeEAO) context.lookup("TimeEAOImpl/remote");
?????? imeEAO.setTimeServer(new Date(), 2);
??? }