@Singleton @Startup @PostConstruct不等待外部客户端调用

时间:2017-01-27 14:35:40

标签: java-ee singleton ejb postconstruct

我在GlassFish 3.1和Jboss AS 6.1中测试了这种行为。

在我的测试中,我已按如下方式配置了一个应用程序: 1)具有Postconstruct方法的Singleton,大约需要1.5分钟才能结束(使用thread.sleep()), 2)一个无状态Bean(名为“Abean”),每30秒运行一次@Schedule方法, 3)一个无状态Bean(名为“Bbean”),在应用程序部署之后由外部客户端请求调用(用于测试EJB 3.1中描述的场景

规范)。 注意:不会在任何EJB bean中注入Singleton。

当我在应用服务器中部署此应用程序时,我可以观察到以下内容:

Jboss和GlassFish服务器都允许预定调用和外部客户端调用到达其目标无状态bean“Abean”和“Bbean”,而Singleton仍在执行其Postconstruct方法。

在我看来,这两个应用服务器都不符合EJB 3.1规范,因为它涉及外部客户端调用(参见参考文献4.8.1 ejb-3_1-fr-specs)。 我还想知道他们的行为是否与预定电话有关(我正在考虑@Startup模式...)

这是我的测试应用程序代码:

Singleton bean

package ejbBeans;

import java.util.Date;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Singleton;
import javax.ejb.Startup;

@Startup
@Singleton
public class TestSessionBeanSingleton {


    @Resource
    SessionContext context;

    public TestSessionBeanSingleton() throws Exception {
        System.out.println("TestSessionBeanSingleton Constructor called");      
    }

    @PostConstruct  
    private void init() {       
        System.out.println("TestSessionBeanSingleton postconstruct called " + new Date());
        try {
            Thread.sleep(90000);
        } catch (InterruptedException e) {
            System.out.println("TestSessionBeanSingleton postconstruct InterruptedException");
        }
        System.out.println("TestSessionBeanSingleton postconstruct End after 1,5 min "  + new Date());
    }



    public void method1() {
        System.out.println("TestSessionBeanSingleton method1 called");
    }
}

无国籍豆“Abean”

package ejbBeans;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.Remote;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;


@Stateless
@Remote(TestInterfaceStateless.class)
public class TestSessionBeanStateless implements TestInterfaceStateless {


    @Resource
    SessionContext context;


    public TestSessionBeanStateless() throws Exception {
        System.out.println("TestSessionBeanStateless Constructor called");      
    }

    @PostConstruct  
    private void init() {
        System.out.println("TestSessionBeanStateless postconstruct called");        
    }

    public void method1(String x, Long y) {
        System.out.println("TestSessionBeanStateless method1 called: String = " + x + " Long = " + y);
    }


}

“Abean”远程接口

package ejbBeans;

public interface TestInterfaceStateless {
    public void method1(String x, Long y);

}

预定方法bean“Bbean”

package ejbBeans;


import javax.annotation.Resource;
import javax.ejb.Schedule;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;

@Stateless
public class TestTimerServiceBean {

    @Resource
    SessionContext sessionContext;

    @Schedule(second="*/30", minute="*",hour="*",persistent=false, info="myScheduled") 
    public void scheduledMethod() {
        System.out.println("TestTimerServiceBean autoScheduledTimedMethod called");
    }

}

外部客户

package ejbClient;

import ejbBeans.TestInterfaceStateless;
import ejbBeans.TestSessionBeanStateless;

public class TestStatelessClient {

    public static void main(String[] args) {
        try {
            TestInterfaceStateless sessionBeanEjb  = (TestInterfaceStateless) ServiceLocator.locateServerSessionBean(TestInterfaceStateless.class, TestSessionBeanStateless.class, ServiceLocator.ViewType.REMOTE);             
            sessionBeanEjb.method1("test",25L);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

外部客户端的服务定位器

package ejbClient;

import java.util.Hashtable;
import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;


public class ServiceLocator {

    public static enum ViewType {
        NO_INTERFACE("no-interface"),
        LOCAL("local"),
        REMOTE("remote");

        private String name;

        private ViewType(String  name) {
            this.name = name;
        }
    }


    protected static Object locateServerSessionBean(Class<?> beanIterface, Class<?> beanClassName, ViewType viewType) {     
        Object bean = null;     
        bean = locateJboss(beanIterface, beanClassName, viewType);
        if (bean == null)
            bean = locateGlassfish(beanIterface, beanClassName, viewType);
        return bean;    
    }


    private static Object locateJboss(Class<?> beanIterface, Class<?> beanClassName, ViewType viewType) {
        String jndiLookupString =  beanClassName.getSimpleName();
        switch (viewType)  {
            case NO_INTERFACE:
                    jndiLookupString += "/" + viewType.name; 
                    break;
            case LOCAL:
            case REMOTE:                
                    jndiLookupString += "/" + viewType.name + "-" + beanIterface.getCanonicalName(); 
                    break;                  
        }
        try {           
            Properties env = new Properties();
            env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
            env.put(Context.PROVIDER_URL, "jnp://localhost:1099");
            InitialContext context = new InitialContext(env);  
            Object bean = context.lookup(jndiLookupString);
            return bean;            
        } catch (Exception e) {
            System.out.println("Locator: bean not found with Jboss name: " +jndiLookupString +", return null");
            return null;
        }       
    }


    private static Object locateGlassfish(Class<?> beanIterface, Class<?> beanClassName, ViewType viewType) {       
        String jndiLookupString =  "java:global/TestStartup/" + beanClassName.getSimpleName() + "!" + beanIterface.getCanonicalName();
        try {
            Hashtable env = new Hashtable();
            env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.enterprise.naming.SerialInitContextFactory");
            InitialContext context = new InitialContext(env); 
            Object bean = context.lookup(jndiLookupString);
            return bean;            
        } catch (Exception e) {
            System.out.println("Locator: bean not found with Glassfish name: " +jndiLookupString +", return null");
            return null;
        }
    }

}

Jboss log

20:16:08,207 WARN  [org.jboss.ejb3.TimerServiceContainer] EJBTHREE-2193: using deprecated TimerServiceFactory for restoring timers
20:16:08,556 INFO  [org.jboss.ejb3.session.SessionSpecContainer] Starting jboss.j2ee:jar=TestStartup.jar,name=TestSessionBeanSingleton,service=EJB3
20:16:08,557 WARN  [org.jboss.ejb3.session.SessionSpecContainer] EJBTHREE-2126: container jboss.j2ee:jar=TestStartup.jar,name=TestSessionBeanSingleton,service=EJB3 does not verify the businessObjectFactory
20:16:08,557 INFO  [org.jboss.ejb3.EJBContainer] STARTED EJB: ejbBeans.TestSessionBeanSingleton ejbName: TestSessionBeanSingleton
20:16:08,557 WARN  [org.jboss.ejb3.TimerServiceContainer] EJBTHREE-2193: using deprecated TimerServiceFactory for restoring timers
20:16:08,559 INFORMAZIONI [STDOUT] TestSessionBeanSingleton Constructor called
20:16:08,739 INFORMAZIONI [STDOUT] TestSessionBeanSingleton postconstruct called Sat Jan 28 20:16:08 CET 2017
20:16:30,055 INFORMAZIONI [STDOUT] TestTimerServiceBean autoScheduledTimedMethod called
20:16:55,733 INFORMAZIONI [STDOUT] TestSessionBeanStateless Constructor called
20:16:55,735 INFORMAZIONI [STDOUT] TestSessionBeanStateless postconstruct called
20:16:55,761 INFORMAZIONI [STDOUT] TestSessionBeanStateless method1 called: String = test Long = 25
20:17:00,006 INFORMAZIONI [STDOUT] TestTimerServiceBean autoScheduledTimedMethod called
20:17:30,023 INFORMAZIONI [STDOUT] TestTimerServiceBean autoScheduledTimedMethod called
20:17:38,740 INFORMAZIONI [STDOUT] TestSessionBeanSingleton postconstruct End after 1,5 min Sat Jan 28 20:17:38 CET 2017
20:17:38,761 INFORMAZIONI [STDOUT] TestSessionBeanSingleton Constructor called
20:17:38,761 INFO  [org.jboss.ejb3.nointerface.impl.jndi.AbstractNoInterfaceViewBinder] Binding the following entry in Global JNDI for bean:TestSessionBeanSingleton

    TestSessionBeanSingleton/no-interface -> EJB3.1 no-interface view

20:17:38,764 INFO  [org.jboss.ejb3.nointerface.impl.jndi.AbstractNoInterfaceViewBinder] Binding the following entry in Global JNDI for bean:TestTimerServiceBean

    TestTimerServiceBean/no-interface -> EJB3.1 no-interface view

20:18:00,004 INFORMAZIONI [STDOUT] TestTimerServiceBean autoScheduledTimedMethod called
20:18:30,003 INFORMAZIONI [STDOUT] TestTimerServiceBean autoScheduledTimedMethod called
20:19:00,002 INFORMAZIONI [STDOUT] TestTimerServiceBean autoScheduledTimedMethod called

GlassFish日志

2017-01-28T22:11:03.025+0100|Informazioni: JTS5014: Recoverable JTS instance, serverId = [3700]
2017-01-28T22:11:03.900+0100|Informazioni: EJB5181:Portable JNDI names for EJB TestSessionBeanStateless: [java:global/TestStartup/TestSessionBeanStateless!ejbBeans.TestInterfaceStateless, java:global/TestStartup/TestSessionBeanStateless]
2017-01-28T22:11:03.900+0100|Informazioni: EJB5182:Glassfish-specific (Non-portable) JNDI names for EJB TestSessionBeanStateless: [ejbBeans.TestInterfaceStateless#ejbBeans.TestInterfaceStateless, ejbBeans.TestInterfaceStateless]
2017-01-28T22:11:03.985+0100|Informazioni: Loading EJBTimerService. Please wait.
2017-01-28T22:11:04.458+0100|Informazioni: WEB0169: Created HTTP listener [http-listener-1] on host/port [0.0.0.0:8080]
2017-01-28T22:11:04.469+0100|Informazioni: WEB0169: Created HTTP listener [http-listener-2] on host/port [0.0.0.0:8181]
2017-01-28T22:11:04.474+0100|Informazioni: WEB0169: Created HTTP listener [admin-listener] on host/port [0.0.0.0:4848]
2017-01-28T22:11:04.523+0100|Informazioni: WEB0171: Created virtual server [server]
2017-01-28T22:11:04.525+0100|Informazioni: WEB0171: Created virtual server [__asadmin]
2017-01-28T22:11:05.020+0100|Informazioni: WEB0172: Virtual server [server] loaded default web module []
2017-01-28T22:11:09.059+0100|Informazioni: HV000001: Hibernate Validator 4.3.0.Final
2017-01-28T22:11:11.256+0100|Informazioni: EclipseLink, version: Eclipse Persistence Services - 2.3.2.v20111125-r10461
2017-01-28T22:11:13.065+0100|Informazioni: file:/C:/Servers/glassfish3/glassfish/domains/domain1/applications/ejb-timer-service-app/WEB-INF/classes/___EJB__Timer__App login successful
2017-01-28T22:11:13.066+0100|Avvertenza: Multiple [2] JMX MBeanServer instances exist, we will use the server at index [0] : [com.sun.enterprise.v3.admin.DynamicInterceptor@11d6ecc3].
2017-01-28T22:11:13.066+0100|Avvertenza: JMX MBeanServer in use: [com.sun.enterprise.v3.admin.DynamicInterceptor@11d6ecc3] from index [0] 
2017-01-28T22:11:13.066+0100|Avvertenza: JMX MBeanServer in use: [com.sun.jmx.mbeanserver.JmxMBeanServer@44c3b4dd] from index [1] 
2017-01-28T22:11:13.133+0100|Informazioni: [TimerBeanContainer] Created  TimerBeanContainer: TimerBean
2017-01-28T22:11:13.163+0100|Informazioni: EJB5181:Portable JNDI names for EJB TimerBean: [java:global/ejb-timer-service-app/TimerBean, java:global/ejb-timer-service-app/TimerBean!com.sun.ejb.containers.TimerLocal]
2017-01-28T22:11:13.367+0100|Informazioni: WEB0671: Loading application [ejb-timer-service-app] at [/ejb-timer-service-app]
2017-01-28T22:11:13.369+0100|Informazioni: EJB5109:EJB Timer Service started successfully for data source [jdbc/__TimerPool]
2017-01-28T22:11:13.372+0100|Informazioni: Setting DBReadBeforeTimeout to false
2017-01-28T22:11:13.372+0100|Informazioni: ==> Restoring Timers ... 
2017-01-28T22:11:13.805+0100|Informazioni: There are no EJB Timers owned by this server
2017-01-28T22:11:13.805+0100|Informazioni: <== ... Timers Restored.
2017-01-28T22:11:13.809+0100|Informazioni: EJB5181:Portable JNDI names for EJB TestTimerServiceBean: [java:global/TestStartup/TestTimerServiceBean, java:global/TestStartup/TestTimerServiceBean!ejbBeans.TestTimerServiceBean]
2017-01-28T22:11:13.836+0100|Informazioni: EJB5181:Portable JNDI names for EJB TestSessionBeanSingleton: [java:global/TestStartup/TestSessionBeanSingleton!ejbBeans.TestSessionBeanSingleton, java:global/TestStartup/TestSessionBeanSingleton]
2017-01-28T22:11:13.840+0100|Informazioni: TestSessionBeanSingleton Constructor called
2017-01-28T22:11:13.869+0100|Informazioni: TestSessionBeanSingleton Constructor called
2017-01-28T22:11:13.873+0100|Informazioni: TestSessionBeanSingleton postconstruct called Sat Jan 28 22:11:13 CET 2017
2017-01-28T22:11:30.015+0100|Informazioni: TestTimerServiceBean autoScheduledTimedMethod called
2017-01-28T22:11:44.763+0100|Informazioni: TestSessionBeanStateless Constructor called
2017-01-28T22:11:44.765+0100|Informazioni: TestSessionBeanStateless postconstruct called
2017-01-28T22:11:44.766+0100|Informazioni: TestSessionBeanStateless method1 called: String = test Long = 25
2017-01-28T22:12:00.002+0100|Informazioni: TestTimerServiceBean autoScheduledTimedMethod called
2017-01-28T22:12:30.002+0100|Informazioni: TestTimerServiceBean autoScheduledTimedMethod called
2017-01-28T22:12:43.873+0100|Informazioni: TestSessionBeanSingleton postconstruct End after 1,5 min Sat Jan 28 22:12:43 CET 2017
2017-01-28T22:12:43.878+0100|Informazioni: CORE10010: Loading application TestStartup done in 109.016 ms
2017-01-28T22:12:43.882+0100|Informazioni: Oracle GlassFish Server 3.1.2.2 (5) startup time : Felix (3.797ms), startup services(110.692ms), total(114.489ms)
2017-01-28T22:12:47.603+0100|Informazioni: JMX005: JMXStartupService had Started JMXConnector on JMXService URL service:jmx:rmi://192.168.1.7:8686/jndi/rmi://192.168.1.7:8686/jmxrmi
2017-01-28T22:13:00.002+0100|Informazioni: TestTimerServiceBean autoScheduledTimedMethod called

0 个答案:

没有答案