如何进行Spring自动装配? [英] How to go about Spring autowiring?

查看:122
本文介绍了如何进行Spring自动装配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public class ProcessSchedulerServlet implements javax.servlet.Servlet {
    Timer timer=new Timer();

    @Override
    public void init(ServletConfig arg0) throws ServletException {
        timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            LogProcessorService logProcessorService=new LogProcessorServiceImpl();
            logProcessorService.processPageRequestsLogs();
        }
     }, 60*1000, 120*1000);
}

这很丑陋,无论如何它是行不通的. LogProcessorServiceImpl具有带有@Autowired批注的属性.在运行此代码时,不会自动连接这些属性.这可能是预期的.

真正的问题是:如何使run()方法起作用.在我看来,Spring希望自动装配logProcessorService以在LogProcessorServiceImpl中具有自动装配的属性.

===场景1 ============================================ ===================

public void run() {
    final LogProcessorService logProcessorService=null;
    WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory().autowireBean(logProcessorService);
    logProcessorService.processPageRequestsLogs();
}

结果:编译时错误:无法在用其他方法定义的内部类中引用非最终变量arg0

===场景2 =========================================== ===================

@Autowired
LogProcessorService logProcessorService;
public void run() {
    logProcessorService.processPageRequestsLogs();
}

结果:运行时错误:logProcessorService为空;

====解决方案(来自鲍里斯)====================================== ================

public class ProcessSchedulerServlet implements javax.servlet.Servlet {
    Timer timer=new Timer();

    @Autowired
    LogProcessorService logProcessorService;

    @Override
    public void init(ServletConfig arg0) throws ServletException {
        final AutowireCapableBeanFactory autowireCapableBeanFactory=WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory();
        autowireCapableBeanFactory.autowireBean(this);

        timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                logProcessorService.processPageRequestsLogs();
            }
        }, 60*1000, 120*1000);
}

解决方案

如果Spring具有 SPR-7022 )./p>

public class ProcessSchedulerServlet implements javax.servlet.Servlet {
    Timer timer=new Timer();

    @Override
    public void init(ServletConfig arg0) throws ServletException {
        timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            LogProcessorService logProcessorService=new LogProcessorServiceImpl();
            logProcessorService.processPageRequestsLogs();
        }
     }, 60*1000, 120*1000);
}

This is ugly and it doesn't work, anyway. The LogProcessorServiceImpl has properties with @Autowired annotation. These properties are not autowired when this code runs. This may be expected.

The real question is: how to make this run() method work. It seems to me that Spring wants the logProcessorService to be autowired to have properties within LogProcessorServiceImpl autowired, as well.

=== SCENARIO 1 ==============================================================

public void run() {
    final LogProcessorService logProcessorService=null;
    WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory().autowireBean(logProcessorService);
    logProcessorService.processPageRequestsLogs();
}

Result: compile time error: Cannot refer to a non-final variable arg0 inside an inner class defined in a different method

=== SCENARIO 2 ==============================================================

@Autowired
LogProcessorService logProcessorService;
public void run() {
    logProcessorService.processPageRequestsLogs();
}

Result: run time error: logProcessorService is null;

==== SOLUTION (from Boris) ======================================================

public class ProcessSchedulerServlet implements javax.servlet.Servlet {
    Timer timer=new Timer();

    @Autowired
    LogProcessorService logProcessorService;

    @Override
    public void init(ServletConfig arg0) throws ServletException {
        final AutowireCapableBeanFactory autowireCapableBeanFactory=WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()).getAutowireCapableBeanFactory();
        autowireCapableBeanFactory.autowireBean(this);

        timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                logProcessorService.processPageRequestsLogs();
            }
        }, 60*1000, 120*1000);
}

解决方案

Why bother with servlets and Timer class if Spring has a built in scheduling support:

@Service
public class LogProcessorService {

    @Scheduled(fixedRate=120*1000, initialDelay=60*1000)
    public void processPageRequestsLogs() {
        //...
    }

}

That's it! No timers, runnables and servlets. Note: initialDelay was introduced in Spring 3.2 M1 (see SPR-7022).

这篇关于如何进行Spring自动装配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆