ejb一些杂的代码
来源:互联网 发布:golang程序员工资 编辑:程序博客网 时间:2024/06/07 17:09
sessionbean
(一)无状态SessionBean(Statless)
(1) 无状态Session Bean单个方法调用就能完成一个完整的业务流程
(2) 无状态Session是可以被重用,不能被客户端并发共享,只可以串行共享,并不保留客户端方法调用后的的状态,而是直接返回。
(3) 无状态的SessionBean是可以池化的(pooling),以优化性能,用以被多个客户共享。
无状态SessionBean的生命周期
如果实例不存在,就会调用构造方法,然后调用资源注入方法,接着会调用有@PostConstruct标注的方法,在销毁时会调用有@PerDestroy标注的方法,
然后销毁对象,如果实例存在就会从Bean实例池中取出实例并调用方法(而不是重新生成实例)。回调方法是基于事件机制的。
接口:
package senssic.ejb.bean;public interface StatlessSession {public void doSomething();}
实现:
package senssic.ejb.bean.impl;import javax.annotation.PostConstruct;import javax.ejb.Remote;import javax.ejb.Stateless;import javax.persistence.PostRemove;import senssic.ejb.bean.StatlessSession;@Stateless@Remote(StatlessSession.class)public class SLSession implements StatlessSession {private int num = 0;@Overridepublic void doSomething() {System.out.println("说说说说,说我爱你,说了:" + num + "次");num++;}@PostConstruct// 创建实例自动被调用的方法public void beforStart() {System.out.println("今天中秋哦,我被实例化了呀");}@PostRemove// 销毁对象时回调此函数public void afterDestory() {System.out.println("连月饼都没有,我被销毁了");}}
打包jar部署到jboss的相应目录下
客户端:
package senssic.test;import java.util.Properties;import javax.naming.InitialContext;import javax.naming.NamingException;import senssic.ejb.bean.StatlessSession;public class Client {public static void main(String[] args) {Properties p = new Properties();p.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");p.setProperty("java.naming.provider.url", "localhost:1099");try {InitialContext cxt = new InitialContext(p);StatlessSession slSession = (StatlessSession) cxt.lookup("SLSession/remote");slSession.doSomething();// 获取第二份无状态bean通过打印的num可以判定只实例化一次被容器放入池中,多个客户端共享一个实例InitialContext cxt2 = new InitialContext(p);StatlessSession slSession2 = (StatlessSession) cxt2.lookup("SLSession/remote");slSession2.doSomething();} catch (NamingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
打印结果:
11:45:26,453 INFO [STDOUT] 今天中秋哦,我被实例化了呀
11:45:26,484 INFO [STDOUT] 说说说说,说我爱你,说了:0次
11:45:26,531 INFO [STDOUT] 说说说说,说我爱你,说了:1次
(二)有状态的SessionBean(Statful)
有状态的SessionBean只为一个客户端服务,不能共享,并且会保留方法调用后的状态。
(1) 多个方法调用才能完成一个业务处理流程;
(2) 需要保留客户端的状态
(3) 不被多个客户共享。
当有状态的SessionBean暂时不被使用时,就会被存储到缓存当中,也就是被存到虚拟内存或者是将信息同步到Session数据��库是应用服务器所提共的小型数据库,用来保存Session的信息,多应用服务器共享Session数据库,同步Bean的信息,达到集群处理)。
实现类的@Stateless改为@Stateful就行了运行结果:
12:13:36,203 INFO [STDOUT] 今天中秋哦,我被实例化了呀
12:13:36,546 INFO [STDOUT] 说说说说,说我爱你,说了:0次
12:13:36,578 INFO [STDOUT] 今天中秋哦,我被实例化了呀
12:13:36,609 INFO [STDOUT] 说说说说,说我爱你,说了:0次
由此可见有状态会话bean每次调用时候容器都会实例化一个新的,就是每个客户端对应一个会话bean
注意:对有状态的SessionBean中有transient属性时,就需要在Bean中提供激活的方法
代码:
package senssic.ejb.bean.impl;import javax.annotation.PostConstruct;import javax.ejb.PostActivate;import javax.ejb.Remote;import javax.ejb.Stateful;import javax.persistence.PostRemove;import senssic.ejb.bean.StatlessSession;@Stateful@Remote(StatlessSession.class)public class SLSession implements StatlessSession {private int num = 0;transient private String str;
@Overridepublic void doSomething() {System.out.println("说说说说,说我爱你,说了:" + num + "次!" + "transient属性:" + str);num++;}@PostConstruct// 创建实例自动被调用的方法public void beforStart() {System.out.println("今天中秋哦,我被实例化了呀");}@PostRemove// 销毁对象时回调此函数public void afterDestory() {System.out.println("连月饼都没有,我被销毁了");}@PostActivate// 使用transient属性时侯使用此注解调用此方法激活public void activate() {str = "我是transient属性因为不能被序列化,所以每次自动调用此方法实例化我";}}
实体bean
实体beanuser:
package senssic.ejb.bean;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;/** * 用户实体 * * @author Senssic@163.com * */@Entity@Table(name = "US")public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(length = 35, name = "US_num")private int num;@Column(length = 35, nullable = false, unique = true, name = "US_name")private String username;@Column(length = 35, nullable = false, name = "US_password")private String password;@Column(length = 45, nullable = false, name = "US_email")private String email;@Column(length = 20, name = "US_relname")private String relname;@Column(length = 35, name = "US_department")private String department;@Column(length = 60, name = "US_address")private String address;@Column(length = 10, name = "US_postcode")private int postcode;@Column(length = 35, name = "US_phone")private String phone;@ManyToOne(cascade = CascadeType.REFRESH)@JoinColumn(name = "AU_num", nullable = false)private Privilege au_num;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public int getNum() {return num;}public void setNum(int num) {this.num = num;}public String getRelname() {return relname;}public void setRelname(String relname) {this.relname = relname;}public String getDepartment() {return department;}public void setDepartment(String department) {this.department = department;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public int getPostcode() {return postcode;}public void setPostcode(int postcode) {this.postcode = postcode;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public Privilege getAu_num() {return au_num;}public void setAu_num(Privilege au_num) {this.au_num = au_num;}}实体beanprivilege:
package webwork.senssic.bean.base;import java.util.Set;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.OneToMany;import javax.persistence.Table;@Entity@Table(name = "AU")public class Privilege {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(length = 35, name = "AU_num")private int num;@Column(length = 35, nullable = false, name = "AU_name")private String name;@Column(length = 50, nullable = false, name = "AU_info")private String info;@OneToMany(mappedBy = "au_num", cascade = CascadeType.ALL)private Set<User> users;public Set<User> getUsers() {return users;}public void setUsers(Set<User> users) {this.users = users;}public int getNum() {return num;}public void setNum(int num) {this.num = num;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}}会话bean
package senssic.ejb.bean;import java.util.List;public interface Manager {public void save(User user);public void update(User user);public void delete(Integer userid);public User getUser(Integer userid);public List<User> getAllUser();public Privilege getPri(Integer pid);}实现:
package senssic.ejb.bean.impl;import java.util.List;import javax.ejb.Remote;import javax.ejb.Stateless;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;import senssic.ejb.bean.Manager;import senssic.ejb.bean.Privilege;import senssic.ejb.bean.User;@Stateless@Remote(Manager.class)public class ManagrImpl implements Manager {// 指定持久化单元的名字,如果只有一个可以不做修改,容器已实例化好,注入即可@PersistenceContext(unitName = "senssic")EntityManager em;@Overridepublic void save(User user) {em.persist(user);}@Overridepublic void update(User user) {em.merge(user);}@Overridepublic void delete(Integer userid) {em.remove(em.getReference(User.class, userid));}@Overridepublic User getUser(Integer userid) {return em.find(User.class, userid);}@SuppressWarnings("unchecked")@Overridepublic List<User> getAllUser() {return em.createQuery("select o from Person o").getResultList();}@Overridepublic Privilege getPri(Integer pid) {return em.find(Privilege.class, pid);}}persistence.xml
<?xml version="1.0"?><persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"><persistence-unit name="senssic" transaction-type="JTA"><jta-data-source>java:senssicDS</jta-data-source></persistence-unit></persistence>mysql-ds.xml文件
<?xml version="1.0" encoding="UTF-8"?><!-- See http://www.jboss.org/community/wiki/Multiple1PC for information about local-tx-datasource --><!-- $Id: mysql-ds.xml 97536 2009-12-08 14:05:07Z jesper.pedersen $ --><!-- Datasource config for MySQL using 3.0.9 available from:http://www.mysql.com/downloads/api-jdbc-stable.html--><datasources> <local-tx-datasource> <jndi-name>senssicDS</jndi-name> <connection-url>jdbc:mysql://localhost:3306/senssic</connection-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <user-name>root</user-name> <password>qiyu0126</password> <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name> <!-- should only be used on drivers after 3.22.1 with "ping" support <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name> --> <!-- sql to call when connection is created <new-connection-sql>some arbitrary sql</new-connection-sql> --> <!-- sql to call on an existing pooled connection when it is obtained from pool - MySQLValidConnectionChecker is preferred for newer drivers <check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql> --> <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) --> <metadata> <type-mapping>mySQL</type-mapping> </metadata> </local-tx-datasource></datasources>测试类:
package senssic.ejb.bean;import static org.junit.Assert.fail;import java.util.Properties;import java.util.Random;import javax.naming.InitialContext;import org.junit.BeforeClass;import org.junit.Test;public class ManagerTest {private static Manager manager;@BeforeClasspublic static void setUpBeforeClass() throws Exception {Properties p = new Properties();p.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");p.setProperty("java.naming.provider.url", "localhost:1099");InitialContext cxt = new InitialContext(p);manager = (Manager) cxt.lookup("ManagrImpl/remote");}@Testpublic void testSave() {User user = new User();Privilege privilege = manager.getPri(1);user.setUsername("煜");user.setEmail("43349267@qq.com");user.setPassword("qiyu");user.setAddress("安徽池州---池州学院");user.setDepartment("池州学院数学系部门");user.setPhone("1325946667");user.setPostcode(1 + new Random().nextInt(10) + 396);user.setRelname("qiyuyu" + new Random().nextInt(100));user.setAu_num(privilege);manager.save(user);}@Testpublic void testUpdate() {fail("Not yet implemented");}@Testpublic void testDelete() {fail("Not yet implemented");}@Testpublic void testGetUser() {fail("Not yet implemented");}@Testpublic void testGetAllUser() {fail("Not yet implemented");}}
jms消息bean
Point-to-Point(PTP)点对点模型
① 消息服务器上用Queue队列来存放消息
② 允许多个消息的生产者发送消息到Queue,但是消息只允许一个消息消费者消费。一旦消息被消费,MOM会把消息从Queue中删除。
修改server\default\deploy\hornetq\hornetq-jms.xml文件添加如下代码:注:因为使用的是6.0的和5.0的配置不一样
<queue name="senssic"> <entry name="/queue/senssic"/> </queue>发送端:
package senssic.mq;import java.util.Properties;import javax.jms.Queue;import javax.jms.QueueConnection;import javax.jms.QueueConnectionFactory;import javax.jms.QueueSender;import javax.jms.QueueSession;import javax.jms.TextMessage;import javax.naming.InitialContext;public class PtoPTo {public static void main(String[] args) {Properties p = new Properties();p.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");p.setProperty("java.naming.provider.url", "localhost:1099");try {InitialContext cxt = new InitialContext(p);QueueConnectionFactory qFactory = (QueueConnectionFactory) cxt.lookup("ConnectionFactory");//此处的QueueConnectionFactory为全局的jndi名称,不能随意更改由jms的各个实现厂商默认提供QueueConnection connection = qFactory.createQueueConnection();QueueSession qSession = connection.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);Queue queue = (Queue) cxt.lookup("queue/senssic");TextMessage msg = qSession.createTextMessage("今年的中秋节没有月饼吃,艹");QueueSender sender = qSession.createSender(queue);sender.send(msg);qSession.close();connection.close();System.out.println("月饼已发送。");} catch (Exception e) {e.printStackTrace();}}}
接受监听结果:
package senssic.mq;import javax.ejb.ActivationConfigProperty;import javax.ejb.MessageDriven;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;@MessageDriven(activationConfig = {@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/senssic"),@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })public class PtoPFrom implements MessageListener {@Overridepublic void onMessage(Message arg0) {TextMessage textMessage = (TextMessage) arg0;try {System.out.println(textMessage.getText());} catch (JMSException e) {e.printStackTrace();}}}
部署运行后结果:
SLSession/remote - EJB3.x Default Remote Business Interface
SLSession/remote-senssic.ejb.bean.StatlessSession - EJB3.x Remote Business Interface
20:56:01,968 INFO [STDOUT] 今年的中秋节没有月饼吃,艹
Publish/Subscribe(pub/sub) 发布/订阅模型
① 用Topic存放消息
② 允许有多个生产者和消费者,同一个消息可被多个消费者消费,且在Topic中不会因消费而删除。
在同样的配置文件下配置如下:
<topic name="qiyu"> <entry name="/topic/qiyu"/> </topic>发送端:
package senssic.mq;import java.util.Properties;import javax.jms.TextMessage;import javax.jms.Topic;import javax.jms.TopicConnection;import javax.jms.TopicConnectionFactory;import javax.jms.TopicPublisher;import javax.jms.TopicSession;import javax.naming.InitialContext;public class TopicTo {public static void main(String[] args) {Properties p = new Properties();p.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");p.setProperty("java.naming.provider.url", "localhost:1099");try {InitialContext cxt = new InitialContext(p);TopicConnectionFactory tFactory = (TopicConnectionFactory) cxt.lookup("ConnectionFactory");TopicConnection connection = tFactory.createTopicConnection();TopicSession tSession = connection.createTopicSession(false,TopicSession.AUTO_ACKNOWLEDGE);Topic topic = (Topic) cxt.lookup("topic/qiyu");TextMessage msg = tSession.createTextMessage("今年的中秋节没有月饼吃,那我就群发月饼………………");TopicPublisher tPublisher = tSession.createPublisher(topic);tPublisher.send(msg);tSession.close();connection.close();System.out.println("月饼已分发。");} catch (Exception e) {e.printStackTrace();}}}
接受端监听结果(可以有多个监听接受):
package senssic.mq;import javax.ejb.ActivationConfigProperty;import javax.ejb.MessageDriven;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageListener;import javax.jms.TextMessage;@MessageDriven(activationConfig = {@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),@ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/qiyu"),@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })public class TopicFrom implements MessageListener {@Overridepublic void onMessage(Message arg0) {TextMessage tMessage = (TextMessage) arg0;try {System.out.println(tMessage.getText());} catch (JMSException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
ejb定时服务
定时器接口:package senssic.ejb.time;public interface MyTimer {public void setScheduleTimer(long milliseconds);}定时器实现:
package senssic.ejb.time;import java.util.Date;import javax.annotation.Resource;import javax.ejb.Remote;import javax.ejb.Stateless;import javax.ejb.Timeout;import javax.ejb.Timer;import javax.ejb.TimerService;@Stateless@Remote(MyTimer.class)public class MyTimerBean implements MyTimer {private static int count = 0;@ResourceTimerService tService;@Overridepublic void setScheduleTimer(long milliseconds) {if (count == 0) {count = 1;tService.createTimer(new Date(new Date().getTime() + milliseconds),milliseconds, "定时分发月饼器。");}}// 每隔指定的时间回调函数@Timeoutpublic void timerout(Timer timer) {System.out.println("-----发了第" + count + "个月饼了------");System.out.println("定时发月饼事件发生传递的月饼为:" + timer.getInfo());if (count > 100) {System.out.println("月饼分发完毕了,亲记得明年早点来哦!");timer.cancel();count = 0;} else {System.out.println("恭喜还有月饼,月饼剩余:" + (100-count) + "个");count++;}}}
测试类:
package senssic.ejb.time;import java.util.Properties;import javax.naming.InitialContext;public class MyTimeTest {/** * @param args */public static void main(String[] args) {Properties p = new Properties();p.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");p.setProperty("java.naming.provider.url", "localhost:1099");try {InitialContext cxt = new InitialContext(p);MyTimer mTimer = (MyTimer) cxt.lookup("MyTimerBean/remote");mTimer.setScheduleTimer(1000);} catch (Exception e) {e.printStackTrace();}}}打印结果:
21:49:56,968 WARN [org.jboss.ejb3.TimerServiceContainer] EJBTHREE-2193: using deprecated TimerServiceFactory for restoring timers
21:50:16,781 INFO [STDOUT] -----发了第1个月饼了------
21:50:16,781 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:16,812 INFO [STDOUT] 恭喜还有月饼,月饼剩余:99个
21:50:17,765 INFO [STDOUT] -----发了第2个月饼了------
21:50:17,765 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:17,765 INFO [STDOUT] 恭喜还有月饼,月饼剩余:98个
21:50:18,750 INFO [STDOUT] -----发了第3个月饼了------
21:50:18,750 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:18,750 INFO [STDOUT] 恭喜还有月饼,月饼剩余:97个
21:50:19,765 INFO [STDOUT] -----发了第4个月饼了------
21:50:19,765 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:19,765 INFO [STDOUT] 恭喜还有月饼,月饼剩余:96个
21:50:20,765 INFO [STDOUT] -----发了第5个月饼了------
21:50:20,765 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:20,765 INFO [STDOUT] 恭喜还有月饼,月饼剩余:95个
21:50:21,750 INFO [STDOUT] -----发了第6个月饼了------
21:50:21,750 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:21,750 INFO [STDOUT] 恭喜还有月饼,月饼剩余:94个
21:50:22,765 INFO [STDOUT] -----发了第7个月饼了------
21:50:22,765 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:22,765 INFO [STDOUT] 恭喜还有月饼,月饼剩余:93个
21:50:23,781 INFO [STDOUT] -----发了第8个月饼了------
21:50:23,781 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:23,781 INFO [STDOUT] 恭喜还有月饼,月饼剩余:92个
21:50:24,781 INFO [STDOUT] -----发了第9个月饼了------
21:50:24,781 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:24,781 INFO [STDOUT] 恭喜还有月饼,月饼剩余:91个
21:50:25,781 INFO [STDOUT] -----发了第10个月饼了------
21:50:25,781 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:25,781 INFO [STDOUT] 恭喜还有月饼,月饼剩余:90个
21:50:26,781 INFO [STDOUT] -----发了第11个月饼了------
21:50:26,781 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:26,781 INFO [STDOUT] 恭喜还有月饼,月饼剩余:89个
21:50:27,781 INFO [STDOUT] -----发了第12个月饼了------
21:50:27,781 INFO [STDOUT] 定时发月饼事件发生传递的月饼为:定时分发月饼器。
21:50:27,781 INFO [STDOUT] 恭喜还有月饼,月饼剩余:88个
- ejb一些杂的代码
- ejb的一些整理资料
- EJB初学者的一些收获和建议
- 关于EJB的一些常见问题(一)
- 关于EJB的一些常见问题(一)
- 关于jboss ejb的一些想法
- EJB使用到的一些名词说明
- 用JBUILD9.0开发EJB的一些步骤和方法
- EJB和WebLogic的一些学习资料收集
- 关于EJB使用中的一些设计模式的说明
- 张孝祥整理的一些面试题(EJB/BEAN/WEBSERVICE)
- 用Kryo做EJB序列化的一些小经验
- HelloWorld EJB代码编写
- HelloWorld EJB代码编写
- 代码风格之EJB
- 通过JNDI远程调用EJB的资源代码
- EJB-EJB的基本分类
- 一些小游戏的代码
- Spring AOP 基本方式(Advice方式)
- 大文本文件阅读器设计
- hadoop集群datanode冲突异常
- 样式与主题
- 高性能网站设计
- ejb一些杂的代码
- 网络专业人士必上的十大专业网站
- 验证码
- 用RadioButten(或CheckBox)实现div的显示与隐藏
- hdu 4004
- wm8650插5V电源,显示电池满和无法接打电话原因。
- Linq查询中获得随机排序的几种方法
- 2014人人笔试题
- ZOJ:2110 Tempter of the Bone