环境:springboot,shiro,oauth
问题:开启登录,使用注解Scheduled 不定时执行任务。
项目中登录采用oauth+shiro实现的单点登录,实现一个starter包,WEB项目客户端集成登录将oauth2-starter包引入, 并通过配置文件决定是否开启登录。
奇怪的就是将配置修改为true时,WEB项目中的定时任务全部失效,为false都正常。
经过debug发现这个问题就和BeanPostProcessor有关。、
该图为bean的生命周期(简化版),当BeanPostProcessor实现类注册到IOC容器后,IOC创建的每个bean实例都会调用BeanPostProcessor的两个方法,调用时刻如上图所示。
publicinterfaceBeanPostProcessor{
//bean初始化方法调用前被调用
ObjectpostProcessBeforeInitialization(Object bean, String beanName)throwsBeansException;
//bean初始化方法调用后被调用
ObjectpostProcessAfterInitialization(Object bean, String beanName)throwsBeansException;
}
而在BeanPostProcessors初始化时经过debug发现有两个ProxyCreator
注解@Scheduled的作用是将交给IOC容器的bean标识有@Scheduled的方法添加到定时任务中, 经过两次代理类创建后,无法获取带有注解@Scheduled方法,这也导致了定时任务失效的原因。
为什么会有两个创建代理类的BeanPostProcessor ?
在shiro的配置文件中有这段代码:
@Bean
public DefaultAdvisorAutoProxyCreatoradvisorAutoProxyCreator(){
DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator =new DefaultAdvisorAutoProxyCreator();
advisorAutoProxyCreator.setProxyTargetClass(true);
return advisorAutoProxyCreator;
}
解决办法:
1.将shiro的这段配置去掉。
2.将使用到注解@Scheduled的类增加一个父类,将定时任务的方法移到父类中即可,父类中不添加任何有关spring的注解。
暂时采用方法2,方法1暂时不确定会不会影响shiro。