zoukankan      html  css  js  c++  java
  • jboss7搭载EJB3之简单会话BEAN与依赖注入jboss数据源

         记录学习的脚步 以备不时之需


    主要涉及到有状态会话Bean与无状态会话Bean ,本地接口与远程接口,依赖注入EJB服务与数据源

      理论方面知识简单提一下吧 毕竟我也说的不是特别精辟

       会话Bean一般用于处理业务层操作,有状态Bean与无状态Bean的区别在于是否记录用户的状态信息  ,有状态Bean记录用户的状态信息,采用(写回(不使用时,将Bean的状态写入硬盘)-激活(需要使用时,从硬盘中恢复其状态信息)机制进行控制),而无状态Bean采用实力池方式控制,类似于数据库连接池

       本地接口与远程接口的区别在于,想要使用本地接口,本地接口与想要使用的业务类代码必须处于一个JVM中,例如部署在一个jboss容器中,本地接口的出现是为了减少远程接口的网络开销、协议解析开销之类的,总之就是加快速度

       依赖注入--都很熟悉了 不解释了

    好吧 用一个HelloWorld展现吧  

      从一个无状态HelloWorld类开始吧

    package com.undergrowth.hello.impl;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import javax.annotation.Resource;
    import javax.ejb.EJB;
    import javax.ejb.Local;
    import javax.ejb.Remote;
    import javax.ejb.Stateless;
    import javax.sql.DataSource;
    
    import com.undergrowth.hello.HelloWorldLocal;
    import com.undergrowth.hello.HelloWorldRemote;
    import com.undergrowth.hello.Other;
    
    
    
    /**
     * Session Bean implementation class HelloWorld
     */
    @Stateless
    @Remote(HelloWorldRemote.class)
    @Local({HelloWorldLocal.class})
    public class HelloWorld implements HelloWorldRemote,HelloWorldLocal {
    
    	//依赖注入其他EJB服务
    	@EJB(beanName="OtherBean") Other other;
    	//注入数据源
    	@Resource(mappedName="java:/myDataSource") DataSource dataSource;
    	/**
         * Default constructor. 
         */
        public HelloWorld() {
            
        }
    
        /**
         * EJB测试方法
         */
    	@Override
    	public String sayHello(String what) {
    		// TODO Auto-generated method stub
    		//通过数据源 获取信息
    		String name=connDb(Integer.valueOf(what));
    		return "你好,"+what+",我是EJB HELLO WORLD!!"+"
    "+other.sayOther(what)+"
    "+"我知道你叫"+name;
    	}
    	
    	/**
    	 * 本该单独分开写的
    	 * 简单处理 就在这写了
    	 * @param id
    	 * @return
    	 */
    	private String connDb(int id)
    	{
    		String str=null;
    		Connection conn = null;
            try {
                conn = dataSource.getConnection();
                Statement stmt = conn.createStatement();
                ResultSet rs = stmt.executeQuery("SELECT st.name from student st WHERE st.id="+id);
                if (rs.next())  str = rs.getString(1);  
                rs.close();
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }finally{
                try {
                    if(null!=conn && !conn.isClosed()) conn.close();
                } catch (SQLException e) {
                 	e.printStackTrace();
                }
            }
            
            return str;
    	}
    }

    看到他有两个实现接口,一个本地,一个远程

    远程接口

    package com.undergrowth.hello;
    
    import javax.ejb.Local;
    import javax.ejb.Remote;
    
    /**
     * 远程接口
     * HelloWorld Remote interface
     */
    
    public interface HelloWorldRemote {
         public String sayHello(String what);
    }
    本地接口

    package com.undergrowth.hello;
    
    /**
     * 本地接口
     * @author Administrator
     *
     */
    public interface HelloWorldLocal {
    	public String sayHello(String what);
    }
    


    哦 还有一个依赖注入的EJB服务 使用@EJB注解

    Other接口

    package com.undergrowth.hello;
    
    /**
     * 测试接口
     * @author Administrator
     *
     */
    public interface Other {
    
    	public  String sayOther(String what);
    }
    

    有状态的Bean 

    package com.undergrowth.hello.impl;
    
    import javax.ejb.Stateless;
    
    import com.undergrowth.hello.Other;
    
    /**
     * 测试@EJB 依赖注入 使用其他EJB服务
     * Other不写Remote或者Local的话 默认为本地接口
     * @author Administrator
     *
     */
    
    @Stateless
    public class OtherBean implements Other {
    
    	@Override
    	public String sayOther(String what) {
    		// TODO Auto-generated method stub
    		return what+",我是other";
    	}
    
    }
    

    好吧  到目前为止 准备了三个接口 一个远程 两个本地  

    还有两个会话Bean,一个有状态  ,一个没有状态

    哦 对了  还有使用了@Resource 注入了jboss数据源 得去配置一下

    在 

    jbossjboss-as-7.1.1.Finalstandaloneconfiguration
    下的standalone.xml中 在

     <subsystem xmlns="urn:jboss:domain:datasources:1.0">
                <datasources>
    元素下添加数据源  修改后如下

    <datasources>
                    <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true">
                        <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url>
                        <driver>h2</driver>
                        <security>
                            <user-name>sa</user-name>
                            <password>sa</password>
                        </security>
                    </datasource>
                    <datasource jta="true" jndi-name="java:/myDataSource" pool-name="OraclesqlDS" enabled="true" use-java-context="true" use-ccm="true">
                        <connection-url>jdbc:oracle:thin:@localhost:1521:orcl</connection-url>
                        <driver>oracle</driver>
                        <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
                        <pool>
                            <min-pool-size>10</min-pool-size>
                            <max-pool-size>100</max-pool-size>
                            <prefill>true</prefill>
                            <use-strict-min>false</use-strict-min>
                            <flush-strategy>FailingConnectionOnly</flush-strategy>
                        </pool>
                        <security>
                            <user-name>u1</user-name>
                            <password>u1</password>
                        </security>
                    </datasource>
                    <drivers>
                        <driver name="h2" module="com.h2database.h2">
                            <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class>
                        </driver>
                        <driver name="oracle" module="com.oracle.ojdbc6">
                            <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
                        </driver>
                    </drivers>
                </datasources>

    因为jboss7的模块化管理     详情可参考  http://vase.iteye.com/blog/1299425

    哦  现在剩下的就是将上面的会话Bean打包 发布到JBOSs中  好的  来个ant的build.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- ================================================ -->
    <!-- Sample buildfile for jar components -->
    <!-- -->
    <!-- ================================================ -->
    <project name="HelloWorld"  basedir=".">
        <!-- 定义属性 -->
        <property name="src.dir" value="${basedir}src" />
        <property environment="env"  />
        <property name="jboss.home" value="${env.JBOSS_HOME}"/>
        <property name="jboss.server.home" value="standalone"  />
        <property name="dep" value="deployments"  />
        <property name="build.dir" value="${basedir}uild"  />
    
        <path id="build.classpath">
        	<fileset dir="${basedir}lib">
        		<include name="*.jar" />
        	</fileset>
        	<pathelement location="${build.dir}" />
        </path>
    
    	<!-- - - - - - - - - - - - - - -->
    	<!-- target: init -->
    	<!-- - - - - - - - - - - - - - -->
    	<target name="init">
    		<delete dir="${build.dir}"></delete>
    		<mkdir dir="${build.dir}"></mkdir>
    	</target>
    
    	<!-- ========================= -->
    	<!-- target: compile -->
    	<!-- ========================= -->
    	<target name="compile" depends="init"
    		description="--> compile  this component" >
    
    		<javac srcdir="${src.dir}" destdir="${build.dir}" includes="com/**">
    			<classpath refid="build.classpath" />
    		</javac>
    	</target>
    	
    	<!-- 打包 -->
    	<target name="ejbjar" depends="compile" description="打包ejb">
    	   <jar jarfile="${basedir}${ant.project.name}.jar">
    	   	<fileset dir="${build.dir}">
    	   		<include name="**/*.class"></include>
    	   	</fileset>
    	   	<metainf dir="${src.dir}META-INF"></metainf>
    	   </jar>
    	</target>
    
        <!-- 部署 -->
        <target name="delopy" depends="ejbjar" description="部署ejb">
        	<copy file="${basedir}${ant.project.name}.jar"  todir="${jboss.home}${jboss.server.home}${dep}" />
        </target>
        
        <!-- 卸载ejb -->
        <target name="undeploy" description="卸载ejb">
          <delete file="${jboss.home}${jboss.server.home}${dep}${ant.project.name}.jar"></delete>
        </target>
        
    	<!-- 打包接口 -->
    	<target name="package_inter" depends="compile" description="打包接口">
    		<jar jarfile="${basedir}${ant.project.name}Interface.jar">
    			   	<fileset dir="${build.dir}">
    			   		<exclude name="**/impl/*.class"></exclude>
    			   	</fileset>
    			   </jar>
    	</target>
    	
    	
    
    </project>
    

    运行ant的deploy 之后 在jboss看到部署信息  

    23:52:03,775 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-2) JNDI bindings for session bean named OtherBean in deployment unit deployment "HelloWorld.jar" are as follows:
    
    	java:global/HelloWorld/OtherBean!com.undergrowth.hello.Other
    	java:app/HelloWorld/OtherBean!com.undergrowth.hello.Other
    	java:module/OtherBean!com.undergrowth.hello.Other
    	java:global/HelloWorld/OtherBean
    	java:app/HelloWorld/OtherBean
    	java:module/OtherBean
    23:52:03,792 INFO  [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-2) JNDI bindings for session bean named HelloWorld in deployment unit deployment "HelloWorld.jar" are as follows:
    
    	java:global/HelloWorld/HelloWorld!com.undergrowth.hello.HelloWorldRemote
    	java:app/HelloWorld/HelloWorld!com.undergrowth.hello.HelloWorldRemote
    	java:module/HelloWorld!com.undergrowth.hello.HelloWorldRemote
    	java:jboss/exported/HelloWorld/HelloWorld!com.undergrowth.hello.HelloWorldRemote
    	java:global/HelloWorld/HelloWorld!com.undergrowth.hello.HelloWorldLocal
    	java:app/HelloWorld/HelloWorld!com.undergrowth.hello.HelloWorldLocal
    	java:module/HelloWorld!com.undergrowth.hello.HelloWorldLocal
    


    看到HelloWorld既有远程接口又有本地接口  而Other只有本地接口


    好了 服务已经在JBOSS的JNDI中了 现在使用客户端进行调用

    运行 ant 的 package_inter  打包接口

    将打包好的接口 拷贝到 客户端测试项目  HelloWorldWeb 中 在index.jsp中 加入一段代码

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%@ page import="javax.naming.*,com.undergrowth.hello.*,com.undergrowth.ejb3.client.*" %>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        
        <title>My JSP 'index.jsp' starting page</title>
    	<meta http-equiv="pragma" content="no-cache">
    	<meta http-equiv="cache-control" content="no-cache">
    	<meta http-equiv="expires" content="0">    
    	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    	<meta http-equiv="description" content="This is my page">
    	<!--
    	<link rel="stylesheet" type="text/css" href="styles.css">
    	-->
      </head>
      
      <body>
        <%
        try {
        //本地接口的使用  需要本地接口与EJB应用在一个JVM里面  本地接口才能找到对应部署的EJB应用
    			HelloWorldLocal helloWorld=HelloWorldClient.lookupRemoteHelloWorldBean();
    			out.println(helloWorld.sayHello("1"));;
    		} catch (NamingException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		
    		
         %>
      </body>
    </html>
    


    这里调用本地接口 因为测试客户端与服务在一个JBOSS中

    JBOSS7的查找JNDI的方法 与之前的版本稍微不一样  如下

    public static HelloWorldLocal lookupRemoteHelloWorldBean() throws NamingException {
    	        final Hashtable jndiProperties = new Hashtable();
    	        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    	        final Context context = new InitialContext(jndiProperties);
    	        // The app name is the application name of the deployed EJBs. This is typically the ear name
    	        // without the .ear suffix. However, the application name could be overridden in the application.xml of the
    	        // EJB deployment on the server.
    	        // Since we haven't deployed the application as a .ear, the app name for us will be an empty string
    	        final String appName = "";
    	        // This is the module name of the deployed EJBs on the server. This is typically the jar name of the
    	        // EJB deployment, without the .jar suffix, but can be overridden via the ejb-jar.xml
    	        // In this example, we have deployed the EJBs in a jboss-as-ejb-remote-app.jar, so the module name is
    	        // jboss-as-ejb-remote-app
    	        final String moduleName = "HelloWorld";
    	        // AS7 allows each deployment to have an (optional) distinct name. We haven't specified a distinct name for
    	        // our EJB deployment, so this is an empty string
    	        final String distinctName = "";
    	        // The EJB name which by default is the simple class name of the bean implementation class
    	        final String beanName = "HelloWorld";
    	        // the remote view fully qualified class name
    	       // final String viewClassName = HelloWorldRemote.class.getName();
    	        final String viewClassName = HelloWorldLocal.class.getName();
    	        // let's do the lookup
    	        return (HelloWorldLocal) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName);
    	        
    	 }

    哦 还有一个 jboss客户端访问jboss服务器的参数文件 文件名为:jboss-ejb-client.properties   放在src目录下即可

    endpoint.name=client-endpoint  
    remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false  
       
    remote.connections=default  
       
    remote.connection.default.host= localhost
    remote.connection.default.port = 4447
    remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false  
      
    remote.connection.default.username=qq     
    remote.connection.default.password=q  


     参考文档  :jboss官方参考手册   https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI


    发布测试客户端 访问index.jsp  输出如下

    你好,1,我是EJB HELLO WORLD!! 1,我是other 我知道你叫Eason 

    即可看到 这里获取JBOSS的JNDI树中发布的服务获取到会话Bean  并转给本地接口 本地接口 进行调用相应的服务 完成功能


    对于JBOSS  真的要赞一下 很好用


  • 相关阅读:
    Geohash
    Go加密解密之RSA[转]
    在MACOS上实现交叉编译
    [转]MySQL与MongoDB的操作对比
    CentOS 6 使用 yum 安装MongoDB及服务器端配置
    Ubuntu下PHP的扩展
    golang 图片处理,剪切,base64数据转换,文件存储
    性能测试应用领域
    性能测试用例、策略和方法
    性能测试类型
  • 原文地址:https://www.cnblogs.com/liangxinzhi/p/4275554.html
Copyright © 2011-2022 走看看