我有一个Spring JobLauncher实现我试图自动装入@Component
类,我们说它叫做SimpleComponent
。这个名为SomeJobLauncher
的作业启动程序通过bean定义加载到Spring上下文中。
如果我在Spring应用程序上下文中自动装入SimpleComponent
,并尝试通过getBean("someLauncher")
获取bean,我会得到我的bean,并且没有问题。
然而,尽管确认bean已100%加载到ApplicationContext中,但当我尝试将someLauncher
自动装入SimpleComponent
时,我收到此错误:
No matching bean of type [com.somepackage.SomeJobLauncher] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
以下是几个相关课程。由于此应用程序的庞大规模,我无法显示每个xml配置文件/ Java类,但如果有特定的内容您希望看到,我可以接受请求。
那么,任何人都可以找到有关如何做到这一点的线索吗?
public class SomeJobLauncher extends BatchScheduleJobLauncher {
private static final long serialVersionUID = 89457928374294789723L;
/**
* Spring inject the appropriate Server name from the Batch properties file.
*/
@Value("${dataload.schedule.server}")
private String jobSchedulerServer;
/**
* No-argument constructor.
*/
public SomeJobLauncher() {
}
@Override
protected String supplyScheduleServer() {
return this.jobobSchedulerServer;
}
}
家长班:
public abstract class BatchScheduleJobLauncher extends SimpleJobLauncher implements Serializable {
private static final long serialVersionUID = -1138294811959957159L;
private String batchJobIdentifier = "not set";
/**
* Set by Spring property setting from the specific JobConfig.xml file inside the
* WEB project.
*/
private Job job;
/**
* Set by Spring property setting from the specific JobConfig.xml file inside the
* WEB project.
*/
private JobLauncher jobLauncher;
/**
* Set by Spring injection from within the descendent's implementation of the supplyScheduleServer
* method.
*/
private String jobSchedulerServer;
/**
* No argument constructor
* Default Constructor
*/
public BatchScheduleJobLauncher() {
}
/**
* Spring invoked method.
*
* @return org.springframework.batch.core.Job - Interface
*/
public Job getJob() {
return this.job;
}
/**
* Spring invoked method.
*
* @return org.springframework.batch.core.launch.JobLauncher - Interface
*/
public JobLauncher getJobLauncher() {
return this.jobLauncher;
}
/**
* Method invoked from the corresponding Job Config XML file in the WEB
* project or from the "Upon Demand" manual invocation process.
*
* @return JobExecution - see internal "Status" for Job Completion
* indication.</br> Status set by this method is either
* BatchStatus.ABANDONED, BatchStatus.COMPLETED or
* BatchStatus.FAILED.
*/
public JobExecution launch() {
JobExecution returnValue;
String timeParameter = "time";
long systemTime = System.currentTimeMillis();
JobParametersBuilder jobParametersBuilder = new JobParametersBuilder();
JobParameters jobParameters;
String ipAddressDefinedServer;
ExitStatus exitStatus;
// Build System Time Job parameter.
jobParametersBuilder.addLong(timeParameter, systemTime);
jobParameters = jobParametersBuilder.toJobParameters();
this.batchJobIdentifier = supplyJobIdentifier();
this.jobSchedulerServer = supplyScheduleServer();
try {
if (Util.isNullOrEmpty(this.jobSchedulerServer)) {
LoggerUtil.error("Batch Job Scheduler Server NOT set on BatchScheduleJobLauncher ancestor class for the [" +
this.batchJobIdentifier + "] Batch Load Job so 'run' could not be executed.");
returnValue = new JobExecution(new JobInstance(new Long(0),
jobParameters,
supplyJobIdentifier()));
exitStatus = new ExitStatus(ExitStatus.FAILED.getExitCode());
returnValue.setExitStatus(exitStatus);
returnValue.setEndTime(new Date());
returnValue.setStatus(BatchStatus.ABANDONED);
} else {
ipAddressDefinedServer = InetAddress.getLocalHost().getHostName();
if (this.jobSchedulerServer.equalsIgnoreCase(ipAddressDefinedServer)) {
// job scheduled server found.
LoggerUtil.info("Executing 'run' from inside the launch method of the BatchScheduleJobLauncher object.");
returnValue = this.jobLauncher.run(this.job, jobParameters);
} else {
LoggerUtil.warn("Batch Job Scheduler Server [" + this.jobSchedulerServer +
"] does NOT match the server name [" + ipAddressDefinedServer +
"] found at IP Address [" + InetAddress.getLocalHost() +
"] so 'run' could not be executed.");
returnValue = new JobExecution(new JobInstance(new Long(0),
jobParameters,
supplyJobIdentifier()));
exitStatus = new ExitStatus(ExitStatus.FAILED.getExitCode());
returnValue.setExitStatus(exitStatus);
returnValue.setEndTime(new Date());
returnValue.setStatus(BatchStatus.ABANDONED);
}
}
} catch (Exception e) {
LoggerUtil.error("ERROR while running the BatchScheduleJobLauncher for the [" +
this.batchJobIdentifier + "] Batch Load Job. Error is [" + e.getMessage()+ "].");
returnValue = new JobExecution(new JobInstance(new Long(0),
jobParameters,
supplyJobIdentifier()));
returnValue.addFailureException(e);
returnValue.setStatus(BatchStatus.FAILED);
}
return returnValue;
}
/**
* Called by Spring based on the property attributes in the corresponding
* Job Config XML file.</br> Sets {@link #job}.
*
* @param org.springframework.batch.core.Job - Interface
*/
public void setJob(Job inJob) {
this.job = inJob;
}
/**
* Called by Spring based on the property attributes in the corresponding
* Job Config XML file.</br> Sets {@link #jobLauncher}.
*
* @param org.springframework.batch.core.Job - Interface
*/
public void setJobLauncher(JobLauncher inJobLauncher) {
this.jobLauncher = inJobLauncher;
}
/**
* Must be implemented by the descendant Job Launcher job to define the type
* of Batch job being run.</br> Sets {@link #batchJobIdentifier}.
*
* @return String - the batch job type.
*/
abstract protected String supplyJobIdentifier();
/**
* Must be implemented by the descendant Job Launcher job to define the
* specific schedule Server name.</br> The appropriate value will be Spring
* injected (see someJobLauncher.java).</br> Sets {@link #jobSchedulerServer}.
*
* @return String - the scheduler server name.
*/
abstract protected String supplyScheduleServer();
}
启动器的Bean定义:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<tx:annotation-driven proxy-target-class="true" />
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
</beans>
作业的Bean定义:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<tx:annotation-driven proxy-target-class="true" />
<!-- Multiple threading not needed so set pool size to one. -->
<task:scheduler id="scheduler" pool-size="1" />
<bean id="someLoadJob" class="com.somepackage.SomeLoadJob" />
<!-- Once Excel File is found on the Load Job landing zone the Batch Load will be run -->
<!-- This Job Instance must always run as a new Job. -->
<batch:job id="processLoadJob" restartable="false">
<batch:step id="processLoadJobStep">
<batch:tasklet ref="LoadJob" />
</batch:step>
</batch:job>
<bean id="someLauncher" class="com.somepackage.SomeJobLauncher">
<property name="jobLauncher" ref="jobLauncher"></property>
<property name="jobRepository" ref="jobRepository"></property>
<property name="job" ref="processLoadJob"></property>
</bean>
<task:scheduled-tasks scheduler="scheduler">
<task:scheduled ref="someLauncher" method="launch" cron="${batch.scheduler.time}"/>
</task:scheduled-tasks>
</beans>
自动上课。你必须明白这个课程正在扫描组件。
@Component
public class SimpleComponent {
private Map<String, JobCategoryStatus> jobStatuses = new HashMap<String, JobCategoryStatus>();;
private Map<String, List<JobCategoryStatus>> categoryStatuses = new HashMap<String, List<JobCategoryStatus>>();
// public SimpleComponent() { };
@Autowired
private ApplicationContext ctx;
//This autowire doesn't work
@Autowired
private SomeJobLauncher someLauncher;
//This method works
public SomeJobLauncher getSomeLauncher() {
Object someLauncher = ctx.getBean("someLauncher");
return someLauncher;
}
}
答案 0 :(得分:0)
我可能会遗漏一些东西,但我没有看到你打开组件扫描()。因为你没有扫描组件而且你的上下文中没有定义SimpleComponent,所以我不希望Spring自动加载它。一旦打开了所需软件包的组件扫描,我希望这可以工作。