【JavaEE】经典JAVA EE企业应用实战-读书笔记9

从目前EJB3来看,EJB其实只有两类

1,会话(SessionBean

2,消息驱动BeanMessage Driven Bean,MDB

 

开发远程调用无状态Session Bean

@Remote
public interface Hello {
	public String hello(String name);
}

@Stateless(mappedName = "Hello")
public class HelloBean implements Hello {
	@Override
	public String hello(String name) {
		return name + ",hello,now time is " + new Date();
	}
}

@Remote专门用于修饰支持远程调用的EJB,即可以修饰接口,也可以修饰Bean的实现类。

@Remote@Local用法几乎完全一样,@Remote允许远程调用,@Local只允许本地调用。

如果EJBBean实现类需要实现多个接口,就必须使用@Local@Remote来修饰。

@Stateless用于修饰支持无状态Session BeanBean实现类,可以指定一个mappedName属性,用于为该EJB指定名称。这个名称并不是该EJBJNDI名。但是EJB容器会根据其属性值生成该EJBJNDI绑定名。

WebLogic的规则是<mappedName>#<业务接口的全限定类名>,如Hello#com.kingdz.service.Hello

JBoss允许开发者不指定其属性值。如果没有指定则为<Bean类名>/remote。如果指定了则为mappedName

对于使用@Local修饰的本地调用的EJB,为@Stateless指定的mappedName属性对于生成JNDI没有任何影响。

注意:如果不是直接将EJB部署在JBoss服务器中,而是先将EJB打包在JavaEE中,然后把这个应用整体部署在JBoss服务器中,那么JBoss为该EJB自动生成JNDI<EAR文件名>/<Bean类名>/remote(远程调用的EJB)或<EAR文件名>/<Bean类名>/local(本地调用的EJB)。

下面是调用的方法:

public class EjbClient {
	public void test() throws Exception {
		Context ctx = getJBossInitialContext();
		Hello h1 = (Hello) ctx.lookup("Hello");
		System.out.println(h1.hello("123"));
	}
	private Context getJBossInitialContext() {
		final String INIT_FACTORY = "org.jnp.interfaces.NamingContextFactory";
		final String SERVER_URL = "localhost:1099";
		Context ctx = null;
		Properties props = new Properties();
		props.put(Context.INITIAL_CONTEXT_FACTORY, INIT_FACTORY);
		props.put(Context.PROVIDER_URL, SERVER_URL);
		try {
			ctx = new InitialContext(props);
		} catch (NamingException e) {
			e.printStackTrace();
		}
		return ctx;
	}
	public static void main(String[] args) {
		try {
			new EjbClient().test();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


本地的@Local的无状态Session Bean与开发远程的相似。区别是需要使用@Local修饰代替@Remote

但是注意,在调用的时候不能使用和远程一样的方式调用,需要部署在服务器上才可以调用。否则会出现

Caused by: java.lang.RuntimeException: Could not find InvokerLocator URL at JNDI address "CatServiceBean/local"; looking up local Proxy from Remote JVM?

可以编写JSP

<%
  InitialContext ctx=new InitialContext();
  Object stub=ctx.lookup(“CatServiceBean/local”);
  CatService cs=(CatService)stub;
  Person p=new Person(1,”haha”);
  Cat[] cats=cs.getCats(new Person(2,”hehe”));
%>

当将本地调用的Session Bean发布在WebLogic服务器后,实际上该Session Bean不仅不能通过远程调用,甚至不能通过该WebLogic中的其他Web程序调用,只能通过与它位于同一个JavaEE应用程序的其他组件来调用,也就是说需要将EJB组件和Web程序打包到一个EAR文件中。

注意:依然保证参数和返回值可以序列化。

这里介绍的两个无状态的Session Bean没有持有任何实例变量,但实际上Session Bean也可以持有实例变量。需要注意的是,不要让Session Bean的实例变量与任何客户机关联——也就是该实例变量可用于记录整个应用的状态,而不能用于记录某个客户机的状态,否则会引起错误。

 

EJB3提供了大量的Annotation,其中用于修饰EJB的业务接口、EJB Bean类的Annotation有如下几个:

@Remote:修饰远程调用的EJB的业务接口或Bean类,修饰业务接口时无须指定任何属性,修饰Bean实现类时则要指定业务接口的类名。

@Local:修饰本地调用的EJB的业务接口或Bean类,修饰业务接口时无须指定任何属性,修饰Bean的实现类时则要指定业务接口的类名。

@Stateful:修饰有状态会话EJBBean类,使用该Annotation时可指定namemappedName两个属性,其中name指定该EJB的名字;mapperedName指定该EJB的全局名。

@Stateless:修饰无状态会话EJBBean类,使用该Annotation时可指定namemappedName两个属性,其中name指定该EJB的名字;mapperedName指定该EJB的全局名。

@MessageDriven:修饰消息驱动EJBBean类,使用该Annotation时可指定namemappedName两个属性,其中name指定该EJB的名字;mapperedName指定该EJB的全局名。除此之外,该Annotation还可指定activationConfig属性,该属性值是多个@ActivationConfigProperty Annotation

@ActivationConfigProperty:也是一个修饰消息驱动BeanAnnotation

public class Cat {
        private String name;
        private Integer age;
}
@Local
public interface CatService {
	Cat[] getCats(Person owner);
}
@Stateless(mappedName="CatService")
public class CatServiceBean implements CatService {
	static Map<Person, Cat[]> catsInfo;
	static {
		catsInfo = new HashMap<Person, Cat[]>();
		catsInfo.put(new Person(1, "p1"), new Cat[] { new Cat("Kitty", 2), new Cat("Garfield", 4) });
	}
	@Override
	public Cat[] getCats(Person owner) {
		return catsInfo.get(owner);
	}
}
public class Person {
	private Integer id;
	private String name;
	public Person() {
	}
	public Person(Integer id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
	@Override
	public boolean equals(Object target) {
		if (this == target) {
			return true;
		}
		if (target.getClass() == Person.class) {
			Person p = (Person) target;
			if (p.getId() == this.getId()) {
				return true;
			}
		}
		return false;
	}
	@Override
	public int hashCode() {
		return this.getId();
	}
}
  上面的注解也可以使用XML来配置。

src\META-INF\ejb-jar.xml

<ejb-jar>
  <enterprise-beans>
    <session>
      <!--指定该EJB的名称-->
      <ejb-name>catService</ejb-name>
      <!--指定该EJB的mappedName-->
      <mapped-name>cs</mapped-name>
      <!--指定该EJB的本地访问的业务接口-->
      <business-local>CatService</business-local>
      <!--指定该EJB的Bean实现类-->
      <ejb-class>CatServiceBean</ejb-class>
      <!--指定该EJB是无状态的Session Bean-->
      <session-type>Stateless</session-type>
    </session>
  </enterprise-beans>
</ebj-jar>
不管是使用Annotation修饰还是XML配置,其实所配置的信息本质上没有改变,只是承载信息的形式不同而已。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值