簡體   English   中英

在ApplicationContext中找到Bean,但在嘗試自動裝配時找不到

[英]Bean found in ApplicationContext, but not found when attempting to Autowire

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



}

我可能會遺漏一些東西,但我沒有看到你打開組件掃描()。 因為你沒有掃描組件而且你的上下文中沒有定義SimpleComponent,所以我不希望Spring自動加載它。 一旦打開組件掃描所需的包,我希望這可以工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM