spring-batch BatchScopeSupport 源码
spring-batch BatchScopeSupport 代码
文件路径:/spring-batch-core/src/main/java/org/springframework/batch/core/scope/BatchScopeSupport.java
/*
* Copyright 2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.scope;
import org.springframework.aop.scope.ScopedProxyUtils;
import org.springframework.batch.core.scope.context.StepContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.BeanDefinitionVisitor;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.Scope;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.Ordered;
import org.springframework.util.Assert;
import org.springframework.util.StringValueResolver;
/**
* ScopeSupport.
*
* @author Michael Minella
* @since 3.0
*/
public abstract class BatchScopeSupport implements Scope, BeanFactoryPostProcessor, Ordered {
private boolean autoProxy = true;
private boolean proxyTargetClass = false;
private String name;
private int order = Ordered.LOWEST_PRECEDENCE;
/**
* @param order the order value to set priority of callback execution for the
* {@link BeanFactoryPostProcessor} part of this scope bean.
*/
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return order;
}
public String getName() {
return this.name;
}
/**
* Public setter for the name property. This can then be used as a bean definition
* attribute, e.g. scope="job".
* @param name the name to set for this scope.
*/
public void setName(String name) {
this.name = name;
}
/**
* Flag to indicate that proxies should use dynamic subclassing. This allows classes
* with no interface to be proxied. Defaults to false.
* @param proxyTargetClass set to true to have proxies created using dynamic
* subclasses
*/
public void setProxyTargetClass(boolean proxyTargetClass) {
this.proxyTargetClass = proxyTargetClass;
}
/**
* Flag to indicate that bean definitions need not be auto proxied. This gives control
* back to the declarer of the bean definition (e.g. in an @Configuration class).
* @param autoProxy the flag value to set (default true)
*/
public void setAutoProxy(boolean autoProxy) {
this.autoProxy = autoProxy;
}
public abstract String getTargetNamePrefix();
/**
* Register this scope with the enclosing BeanFactory.
*
* @see BeanFactoryPostProcessor#postProcessBeanFactory(ConfigurableListableBeanFactory)
* @param beanFactory the BeanFactory to register with
* @throws BeansException if there is a problem.
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
beanFactory.registerScope(name, this);
if (!autoProxy) {
return;
}
Assert.state(beanFactory instanceof BeanDefinitionRegistry,
"BeanFactory was not a BeanDefinitionRegistry, so JobScope cannot be used.");
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
for (String beanName : beanFactory.getBeanDefinitionNames()) {
if (!beanName.startsWith(getTargetNamePrefix())) {
BeanDefinition definition = beanFactory.getBeanDefinition(beanName);
// Replace this or any of its inner beans with scoped proxy if it
// has this scope
boolean scoped = name.equals(definition.getScope());
Scopifier scopifier = new Scopifier(registry, name, proxyTargetClass, scoped);
scopifier.visitBeanDefinition(definition);
if (scoped && !definition.isAbstract()) {
createScopedProxy(beanName, definition, registry, proxyTargetClass);
}
}
}
}
/**
* Wrap a target bean definition in a proxy that defers initialization until after the
* {@link StepContext} is available. Amounts to adding <aop-auto-proxy/> to a
* step scoped bean.
* @param beanName the bean name to replace
* @param definition the bean definition to replace
* @param registry the enclosing {@link BeanDefinitionRegistry}
* @param proxyTargetClass true if we need to force use of dynamic subclasses
* @return a {@link BeanDefinitionHolder} for the new representation of the target.
* Caller should register it if needed to be visible at top level in bean factory.
*/
protected static BeanDefinitionHolder createScopedProxy(String beanName, BeanDefinition definition,
BeanDefinitionRegistry registry, boolean proxyTargetClass) {
BeanDefinitionHolder proxyHolder;
proxyHolder = ScopedProxyUtils.createScopedProxy(new BeanDefinitionHolder(definition, beanName), registry,
proxyTargetClass);
registry.registerBeanDefinition(beanName, proxyHolder.getBeanDefinition());
return proxyHolder;
}
/**
* Helper class to scan a bean definition hierarchy and force the use of auto-proxy
* for step scoped beans.
*
* @author Dave Syer
*
*/
protected static class Scopifier extends BeanDefinitionVisitor {
private final boolean proxyTargetClass;
private final BeanDefinitionRegistry registry;
private final String scope;
private final boolean scoped;
public Scopifier(BeanDefinitionRegistry registry, String scope, boolean proxyTargetClass, boolean scoped) {
super(new StringValueResolver() {
@Override
public String resolveStringValue(String value) {
return value;
}
});
this.registry = registry;
this.proxyTargetClass = proxyTargetClass;
this.scope = scope;
this.scoped = scoped;
}
@Override
protected Object resolveValue(Object value) {
BeanDefinition definition = null;
String beanName = null;
if (value instanceof BeanDefinition) {
definition = (BeanDefinition) value;
beanName = BeanDefinitionReaderUtils.generateBeanName(definition, registry);
}
else if (value instanceof BeanDefinitionHolder) {
BeanDefinitionHolder holder = (BeanDefinitionHolder) value;
definition = holder.getBeanDefinition();
beanName = holder.getBeanName();
}
if (definition != null) {
boolean nestedScoped = scope.equals(definition.getScope());
boolean scopeChangeRequiresProxy = !scoped && nestedScoped;
if (scopeChangeRequiresProxy) {
// Exit here so that nested inner bean definitions are not
// analysed
return createScopedProxy(beanName, definition, registry, proxyTargetClass);
}
}
// Nested inner bean definitions are recursively analysed here
value = super.resolveValue(value);
return value;
}
}
}
相关信息
相关文章
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
8、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦