class AbstractJobExplorerFactoryBean implements FactoryBean<JobExplorer>, InitializingBean {

	private static final String TRANSACTION_ISOLATION_LEVEL_PREFIX = "ISOLATION_";

	private static final String TRANSACTION_PROPAGATION_PREFIX = "PROPAGATION_";

	private PlatformTransactionManager transactionManager;

	private TransactionAttributeSource transactionAttributeSource;

	private final ProxyFactory proxyFactory = new ProxyFactory();

	/**
	 * Creates a job instance data access object (DAO).
	 * @return a fully configured {@link JobInstanceDao} implementation.
	 * @throws Exception thrown if error occurs during JobInstanceDao creation.
	 */
	protected abstract JobInstanceDao createJobInstanceDao() throws Exception;

	/**
	 * Creates a job execution data access object (DAO).
	 * @return a fully configured {@link JobExecutionDao} implementation.
	 * @throws Exception thrown if error occurs during JobExecutionDao creation.
	 */
	protected abstract JobExecutionDao createJobExecutionDao() throws Exception;

	/**
	 * Creates a step execution data access object (DAO).
	 * @return a fully configured {@link StepExecutionDao} implementation.
	 * @throws Exception thrown if error occurs during StepExecutionDao creation.
	 */
	protected abstract StepExecutionDao createStepExecutionDao() throws Exception;

	/**
	 * Creates an execution context instance data access object (DAO).
	 * @return fully configured {@link ExecutionContextDao} implementation.
	 * @throws Exception thrown if error occurs during ExecutionContextDao creation.
	 */
	protected abstract ExecutionContextDao createExecutionContextDao() throws Exception;

	/**
	 * Public setter for the {@link PlatformTransactionManager}.
	 * @param transactionManager the transactionManager to set
	 * @since 5.0
	 */
	public void setTransactionManager(PlatformTransactionManager transactionManager) {
		this.transactionManager = transactionManager;
	}

	/**
	 * The transaction manager used in this factory. Useful to inject into steps and jobs,
	 * to ensure that they are using the same instance.
	 * @return the transactionManager
	 * @since 5.0
	 */
	public PlatformTransactionManager getTransactionManager() {
		return this.transactionManager;
	}

	/**
	 * Set the transaction attributes source to use in the created proxy.
	 * @param transactionAttributeSource the transaction attributes source to use in the
	 * created proxy.
	 * @since 5.0
	 */
	public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
		Assert.notNull(transactionAttributeSource, "transactionAttributeSource must not be null.");
		this.transactionAttributeSource = transactionAttributeSource;
	}

	@Override
	public void afterPropertiesSet() throws Exception {<FILL_FUNCTION_BODY>}

	/**
	 * Returns the type of object to be returned from {@link #getObject()}.
	 * @return {@code JobExplorer.class}
	 * @see org.springframework.beans.factory.FactoryBean#getObjectType()
	 */
	@Override
	public Class<JobExplorer> getObjectType() {
		return JobExplorer.class;
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

	@Override
	public JobExplorer getObject() throws Exception {
		TransactionInterceptor advice = new TransactionInterceptor((TransactionManager) this.transactionManager,
				this.transactionAttributeSource);
		proxyFactory.addAdvice(advice);
		proxyFactory.setProxyTargetClass(false);
		proxyFactory.addInterface(JobExplorer.class);
		proxyFactory.setTarget(getTarget());
		return (JobExplorer) proxyFactory.getProxy(getClass().getClassLoader());
	}

	private JobExplorer getTarget() throws Exception {
		return new SimpleJobExplorer(createJobInstanceDao(), createJobExecutionDao(), createStepExecutionDao(),
				createExecutionContextDao());
	}

}

		Assert.notNull(this.transactionManager, "TransactionManager must not be null.");
		if (this.transactionAttributeSource == null) {
			Properties transactionAttributes = new Properties();
			String transactionProperties = String.join(",", TRANSACTION_PROPAGATION_PREFIX + Propagation.SUPPORTS,
					TRANSACTION_ISOLATION_LEVEL_PREFIX + Isolation.DEFAULT);
			transactionAttributes.setProperty("get*", transactionProperties);
			transactionAttributes.setProperty("find*", transactionProperties);
			this.transactionAttributeSource = new NameMatchTransactionAttributeSource();
			((NameMatchTransactionAttributeSource) this.transactionAttributeSource)
				.setProperties(transactionAttributes);
		}
	
<no_super_class>