背景
最近做spring与quartz整合。业务实现时,需要在job里引入spring的bean,但是job的初始化时quartz在执行时new出来的。不受spring的管理,无法注入相关的依赖bean。多方查阅资料后,发现AutowireCapableBeanFactory可以实现类似功能。下面就通过走读代码的方式来学习下这个类的用法。
进入正题
首先来看下AutowireCapableBeanFactory的定义:
public interface AutowireCapableBeanFactory extends BeanFactory {
<T> T createBean(Class<T> beanClass) throws BeansException;
void autowireBean(Object existingBean) throws BeansException;
Object configureBean(Object existingBean, String beanName) throws BeansException;
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
Object initializeBean(Object existingBean, String beanName) throws BeansException;
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
void destroyBean(Object existingBean);
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException;
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;
}
该类的注释中有这么一句话Integration code for other frameworks can leverage this interface to wire and populate existing bean instances that Spring does not control the lifecycle of
,意思是说该类可以填充那些不受spring容器控制的bean。
spring和quartz在集成的时候用了autowireBean方法。下面走读这个方法的代码来看处理逻辑。
autowireBean的实现在类AbstractAutowireCapableBeanFactory中。
代码如下
public void autowireBean(Object existingBean) {
// Use non-singleton bean definition, to avoid registering bean as dependent bean.
RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), getBeanClassLoader());
BeanWrapper bw = new BeanWrapperImpl(existingBean);
initBeanWrapper(bw);
populateBean(bd.getBeanClass().getName(), bd, bw);
}
该方法的逻辑主要在populateBean中。这个方法是spring里很重要的一个方法,用于装配bean。这里逻辑很复杂,主要是通过反射获取我们new出来的对象的属性及注解。若注解是Autowired,Value,Inject时,进行bean的组装。此方法执行完成之后。我们new出来的对象里通过注解注入的bean就可以使用了。
关键代码展示:
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
......
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//依赖的bean注入在这里实现
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
//end
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
applyPropertyValues(beanName, mbd, bw, pvs);
}
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
//获取注入的属性
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
例子
quartz 的job里注入bean:
job 工厂:
public class JobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
//进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
job的具体处理逻辑
public final class InternalJob implements Job {
private static final Logger logger = LoggerFactory.getLogger(InternalJob .class);
@Autowired
private CuratorFramework client;
@Autowired
private JobAlarmEventService jobAlarmEventService;
job的spring配置:
<bean id="jobFactory" class="com.test.scheduler.JobFactory"></bean>
<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory" ref="jobFactory"></property>
<property name="schedulerName" value="scheduler"></property>
<property name="configLocation" value="classpath:META-INF/spring/quartz.properties"></property>
</bean>