在ApplicationContext中找到Bean,但在尝试自动装配时找不到

时间:2014-01-14 19:08:15

标签: java xml spring spring-batch

我有一个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;
    }



}

1 个答案:

答案 0 :(得分:0)

我可能会遗漏一些东西,但我没有看到你打开组件扫描()。因为你没有扫描组件而且你的上下文中没有定义SimpleComponent,所以我不希望Spring自动加载它。一旦打开了所需软件包的组件扫描,我希望这可以工作。