001/* 002 * Copyright 2013 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.springframework.batch.core.jsr.configuration.support; 017 018import org.springframework.beans.BeansException; 019import org.springframework.beans.PropertyValue; 020import org.springframework.beans.factory.BeanFactory; 021import org.springframework.beans.factory.config.BeanDefinition; 022import org.springframework.beans.factory.config.BeanFactoryPostProcessor; 023import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 024import org.springframework.beans.factory.config.RuntimeBeanReference; 025import org.springframework.beans.factory.support.AbstractBeanDefinition; 026import org.springframework.beans.factory.support.BeanDefinitionBuilder; 027import org.springframework.beans.factory.support.DefaultListableBeanFactory; 028import org.springframework.core.PriorityOrdered; 029 030/** 031 * After the {@link BeanFactory} is created, this post processor will evaluate to see 032 * if any of the beans referenced from a job definition (as defined by JSR-352) point 033 * to class names instead of bean names. If this is the case, a new {@link BeanDefinition} 034 * is added with the name of the class as the bean name. 035 * 036 * @author Michael Minella 037 * @since 3.0 038 */ 039public class ThreadLocalClassloaderBeanPostProcessor implements BeanFactoryPostProcessor, PriorityOrdered { 040 /* (non-Javadoc) 041 * @see org.springframework.beans.factory.config.BeanFactoryPostProcessor#postProcessBeanFactory(org.springframework.beans.factory.config.ConfigurableListableBeanFactory) 042 */ 043 @Override 044 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 045 String[] beanNames = beanFactory.getBeanDefinitionNames(); 046 047 for (String curName : beanNames) { 048 BeanDefinition beanDefinition = beanFactory.getBeanDefinition(curName); 049 PropertyValue[] values = beanDefinition.getPropertyValues().getPropertyValues(); 050 051 for (PropertyValue propertyValue : values) { 052 Object value = propertyValue.getValue(); 053 054 if(value instanceof RuntimeBeanReference) { 055 RuntimeBeanReference ref = (RuntimeBeanReference) value; 056 if(!beanFactory.containsBean(ref.getBeanName())) { 057 AbstractBeanDefinition newBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(ref.getBeanName()).getBeanDefinition(); 058 newBeanDefinition.setScope("step"); 059 ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition(ref.getBeanName(), newBeanDefinition); 060 } 061 } 062 } 063 } 064 } 065 066 /** 067 * Sets this {@link BeanFactoryPostProcessor} to the lowest precedence so that 068 * it is executed as late as possible in the chain of {@link BeanFactoryPostProcessor}s 069 */ 070 @Override 071 public int getOrder() { 072 return PriorityOrdered.LOWEST_PRECEDENCE; 073 } 074}