春季应用程序启动后如何在后台启动方法

时间:2013-08-28 18:50:01

标签: java spring background initialization

我有执行Url扫描的方法,我需要在加载所有弹簧配置后在背景中启动它。我尝试使用InitializingBean,但是进程不在后台进行循环,配置永远不会结束。请给我任何关于这个问题的宣传。谢谢。

public class ScheduledScanner implements InitializingBean {

    protected static Logger logger = Logger.getLogger(ScheduledScanner.class);

    protected final static String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0";

    private static final int MYTHREADS = 30;

    private Date date = new Date();

    private Timestamp timestamp = new Timestamp(date.getTime());

    private AdminService adminService;

    private EmployeeService employeeService;

    private ConfigurableApplicationContext context =
            new ClassPathXmlApplicationContext(new String[]{"classpath:application-context.xml"});

    @Autowired
    public void setAdminService(AdminService adminService) {
        this.adminService = adminService;
    }

    @Autowired
    public void setEmployeeService(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    /**
     * Sends GET request to @param ip: @param port with Apache HttpClient
     * <p/>
     * param ip      - must contain URL or IP of target server;
     * param port    - for server target Port;
     * param timeout - sets the time for request timeout before no respond;
     * <p/>
     * ServerState enum:
     * OK - server is up and responding correctly
     * WARN  - server is running, but returns a response to the HTTP - code different than 200
     * FAIL - the server is not responding, or responds with HTTP code, such as 500
     * <p/>
     * - all other info: http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/Response.Status.html
     */
    public void afterPropertiesSet() throws Exception {

        logger.debug("ServletContextListener started");

        final List<ServerEntity> listToScan = adminService.getAllServers();

        final SystemSettingsModel settings = employeeService.getSettingsByName("default");

        // setting task to execute;
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(MYTHREADS);
ApplicationContext context =
            new ClassPathXmlApplicationContext(new String[]{"classpath:application-context.xml"});
        scheduler.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {

                // iterating list of all servers
                for (ServerEntity serverEntity : listToScan) {

                    // check if state of server is active
                    if (serverEntity.getActive().equals(1)) {

                        ServerState state;

                        try {
                            // setting URL or IP eith Port of target address
                            URL obj = new URL(serverEntity.getAddress() + ":" + serverEntity.getPort());

                            // establishing connection
                            HttpURLConnection con = (HttpURLConnection) obj.openConnection();
                            con.setRequestMethod("GET");

                            // setting timeout of response
                            con.setConnectTimeout(settings.getTimeoutOfRespond());

                            // add request header
                            con.setRequestProperty("User-Agent", USER_AGENT);

                            if (con.getResponseCode() == 200) {
                                state = ServerState.OK;
                            } else if (con.getResponseCode() == 500) {
                                state = ServerState.FAIL;   // Internal Server Error
                            } else {
                                state = ServerState.WARN;   // BAD_REQUEST or other conflict
                            }
                        } catch (Exception e) {
                            state = ServerState.FAIL;
                        }

                        // saving response from server
                        serverEntity.setState(state);
                        serverEntity.setResponse(state.toString());
                        serverEntity.setLastCheck(timestamp);
                        adminService.updateServer(serverEntity);
                    }   // if
                }   // run()
            }   // for
            /*
             * Scheduling Fixed Rate of scan
             *
             * param initialDelay the time to delay first execution;
             * param period the period between successive executions;
             * param unit the time unit of the initialDelay and period parameters;
             */
        }, 0, settings.getServerScanInterval(), TimeUnit.SECONDS);
    }   // executeScanner()
}

在调试中,app开始循环这一行:

(DefaultListableBeanFactory.java:preInstantiateSingletons:596) Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@410bf486: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,adminPasswordUpdateController,adminSettingsController,employeeDeleteController,employeeEditController,employeeManagementController,employeeRegistrationController,serverAssignmentController,serverDeleteController,serverEditController,serverManagementController,serverRegistrationController,employeePasswordUpdateController,serverDetailsController,serverMonitoringController,loginLogoutController,passwordRecoveryController,employeeJdbcDaoSupport,serverJdbcDaoSupport,settingsJdbcDaoSupport,AdminServiceImpl,AnonymousServiceImpl,EmployeeServiceImpl,userAuthentication,customUtilsImpl,CustomMailDeliveryImpl,scheduledScanner,simpleScannerImpl,employeeRegistrationValidator,employeeUpdateValidatior,passwordRecoveryValidator,passwordUpdateValidator,serverRegistrationValidator,settingsUpdateValidator,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0,org.springframework.transaction.interceptor.TransactionInterceptor#0,org.springframework.transaction.config.internalTransactionAdvisor,txManager,dataSource,org.springframework.jdbc.datasource.init.DataSourceInitializer#0,log4jInitialization,mvcContentNegotiationManager,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.web.servlet.resource.ResourceHttpRequestHandler#0,org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0,org.springframework.web.servlet.handler.MappedInterceptor#1,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy

更新: 我删除了@Component注释并删除了配置行中的循环,但是方法没有像预期的那样循环。

这是application-context.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <!-- Activates annotations scan, declares support for all the general annotations
        like @Autowired, @Resource, @Required, @PostConstruct-->
    <context:annotation-config/>

    <!-- Scans for annotated components in base-package -->
    <context:component-scan base-package="serverMonitoring"/>

    <!-- Spring modules -->
    <import resource="classpath:/spring/spring-data-source.xml"/>
    <import resource="classpath:/spring/spring-logging.xml"/>
    <import resource="classpath:/spring/spring-mvc.xml"/>
    <import resource="classpath:/spring/spring-mail.xml"/>


    <bean id="scheduledScanner" class="serverMonitoring.util.network.impl.ScheduledScanner" />

</beans>

尽管如此,我的scaner并没有执行扫描循环。

2 个答案:

答案 0 :(得分:2)

您的代码在其他地方阻止,而不是SchedulerExecutorService。下面的代码工作正常。

public static class MyBean implements InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(13);
        scheduler.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello from scheduler");                 
            }
        }, 0, 5, TimeUnit.SECONDS);
    }

} 

@Configuration
public static class Config {
    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}

public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
    System.out.println(context.getBean(MyBean.class));
}

答案 1 :(得分:0)

我解决了这个问题。主要问题是在服务级别上抛出了AuthenticationCredentialsNotFoundException,因此在使用上下文和初始化几天后,我用DAO级别更改了服务级别并返回了@Component注释。