ScheduledAnnotationBeanPostProcessor没有完成注册()

den*_*nov 7 java spring spring-scheduled spring-java-config

在调试为什么我的@scheduled方法没有触发时,我将问题追溯到ScheduledAnnotationBeanPostProcessor.

调用afterSingletonsInstantiated()后,applicationContent已经设置,因此不会调用finishRegistration().

然后onApplicationEvent()似乎永远不会被调用.contextRefresh事件正在作为我使用的调用的StartUpHouseKeeping类发布

@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) { ... }
Run Code Online (Sandbox Code Playgroud)

如果我在afterSingletonsInstantiated()中坚持一个断点并手动调用finishRegistration()就可以正常工作.

我正在使用java配置而没有web.xml

AppInit.java

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    private static final Logger log = LoggerFactory.getLogger(AppInitializer.class);

    private static final String[] NO_CACHE_URLS = new String[]{"*.appcache", "*.webapp", "/static/js/*", "/static/css/*", "/api/*", "/ping"};


    public AppInitializer() {
        log.info("** App Initializer **");
    }


    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
    }


    @Override
    protected WebApplicationContext createRootApplicationContext() {
        // ((ConfigurableEnvironment)context.getEnvironment()).addActiveProfile(_env.getProperty("env", "local"));
        return super.createRootApplicationContext();

    }


    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { AppConfig.class };
    }


    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { WebConfig.class };
    }


    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }


    @Override
    protected FrameworkServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
        final DispatcherServlet servlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
        servlet.setThrowExceptionIfNoHandlerFound(true);
        return servlet;
    }


    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        registration.setInitParameter("trimSpace", "true");
        registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");

        super.customizeRegistration(registration);
    }


    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("UTF-8");
        encodingFilter.setForceEncoding(true);

        return new Filter[] { encodingFilter,
                              new MdcLoggingFilter(),
                              new HiddenHttpMethodFilter(),
                              new HttpPutFormContentFilter(),
                              new GZIPFilter(),
                              new DelegatingFilterProxy(AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)};
    }


    @Override
    protected void registerDispatcherServlet(ServletContext servletContext) {
        log.info("Configuring servlet context");

        servletContext.setInitParameter("defaultHtmlEscape", "tue");
        servletContext.setInitParameter("throwExceptionIfNoHandlerFound", "true");
        servletContext.addListener(new SessionListener());

        servletContext.addFilter("UrlRewriteFilter", new UrlRewriteFilter()).addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD), true, "/*");
        servletContext.addFilter("NoCacheControl", new NoCacheFilter()).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, NO_CACHE_URLS);

        super.registerDispatcherServlet(servletContext);  // this ends up calling - getServletFilters()
    }

}
Run Code Online (Sandbox Code Playgroud)

AppConfig.java

@Configuration
@ComponentScan(basePackages="org.magic",
               excludeFilters={ @ComponentScan.Filter(type=FilterType.ANNOTATION, value={ Controller.class }),
                                @ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE, value={ SwaggerConfig.class, WebConfig.class }) })
@EnableAspectJAutoProxy
@PropertySource(value = { "classpath:spring/application.${env:local}.properties" })
public class AppConfig  {   
  ....
}
Run Code Online (Sandbox Code Playgroud)

ScheduleConfig.java

@Configuration
@EnableAsync
@EnableScheduling
public class ScheduleConfig implements SchedulingConfigurer, AsyncConfigurer  {

    private static final Logger log = LoggerFactory.getLogger(ScheduleConfig.class);


    public ScheduleConfig() {
        log.info("loading scheduling config");
    }


    @Bean
    public DistributiveEventMulticaster applicationEventMulticaster() {
        SimpleApplicationEventMulticaster asyncMulticaster = new SimpleApplicationEventMulticaster();
        asyncMulticaster.setTaskExecutor(getAsyncExecutor());
        return new DistributiveEventMulticaster(asyncMulticaster, new SimpleApplicationEventMulticaster());
    }


    @Bean(name = "taskExecutor", destroyMethod="shutdownNow")
    public Executor taskExecutor() {
        ScheduledExecutorService delegateExecutor = Executors.newScheduledThreadPool(10);
        return new DelegatingSecurityContextScheduledExecutorService(delegateExecutor, createSchedulerSecurityContext());
    }


    @Override
    @Bean(name = "asyncExecutor")
    public Executor getAsyncExecutor() {
        ContextAwarePoolExecutor executor = new ContextAwarePoolExecutor(); //new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(15);
        executor.setDaemon(true);
        executor.setThreadNamePrefix("AsyncExecutor-");
        executor.initialize();
        return new DelegatingSecurityContextExecutor(executor);
    }


    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new MyAsyncUncaughtExceptionHandler();
    }


    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }


    private SecurityContext createSchedulerSecurityContext() {
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        Collection<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_USER");
        Authentication authentication = new UsernamePasswordAuthenticationToken("nightly tasks", Credentials.SYSTEM, authorities);
        context.setAuthentication(authentication);
        return context;
    }
}
Run Code Online (Sandbox Code Playgroud)