在控制器内的@postconstruct方法中实例化一个@autowired bean,spring

时间:2017-03-25 08:49:28

标签: java spring jsp spring-mvc

我想为所有控制器调用一个公共服务,以获取一个带有一些常见对象的commmon ModelAndView对象。

所以我为所有控制器创建了一个超类--BaseController,我通过调用一个方法initCommonData来启动BaseController构造函数中的公共模型对象,该方法使用@Autowired bean CommonDataService,它在构造中不存在对象的时间并返回null,所以我应该怎么做才能在构造函数中获得@autowired依赖。

仅供参考 - 我正在使用这个常用服务和常用数据来获取一些商品数据,这些数据将用于网站页眉和页脚中的每个jsp。 因此,如果在不调用每个控制器方法中的公共服务的情况下有另一种方法,请在每个控制器中建议。 这是我的代码 - BaseController

@Controller
public class BaseController {

@Autowired
private CommonDataService commonDataService;

protected ModelAndView model; 

public BaseController() {
    this.initCommonData();
}

public void initCommonData(){
    this.model = new ModelAndView();
    this.model.addObject("headerData",commonDataService.getHeaderData());
    this.model.addObject("footerData",commonDataService.getFooterData());
}

子类控制器 -

@Controller
public class HomeController extends BaseController {

@Autowired
CategoryService categoryService;

@Autowired
CompanyService companyService;

@RequestMapping(value = { "", "/", "home" })
public ModelAndView homePage() {
    model.setViewName("home");
    .
    .
    .
    model.addObject("name", value);
    model.addObject("name2", value2);
    return model;
}

CommonServiceClass -

@Service
public class CommonDataService {

@Autowired
CompanyService companyService;

@Autowired
CategoryService categoryService;

@Cacheable
public List<Category> getHeaderData(){
    return categoryService.getTopCategoryList();
}

@Cacheable
public List<Company> getFooterData(){
    return companyService.getTopCompanyList();
}

请建议是否有其他好的方法,从服务器获取常用数据到jsp。

2 个答案:

答案 0 :(得分:1)

无论@Andreas建议什么是最佳解决方案,即将BaseController标记为abstract并使用@Postconstruct。由于BaseController本身在您的情况下不拥有任何网址映射,因此不会将其标记为@Controller

由于任何原因,如果您正在寻找其他选项,可以考虑将BaseController标记为@Component并将@Postconstruct用于initCommonData,以便此方法将弹簧容器加载BaseController bean后自动调用:

@Component
public class BaseController {

   @Autowired
   private CommonDataService commonDataService;

   protected ModelAndView model; 

    @Postconstruct
    public void initCommonData(){
       this.model = new ModelAndView();
       this.model.addObject("headerData",commonDataService.getHeaderData());
       this.model.addObject("footerData",commonDataService.getFooterData());
    }
 }

答案 1 :(得分:1)

首先,从基类中删除@Controller。您甚至可以使类abstract帮助指示/记录它必须是子类。

接下来,不要从构造函数中调用initCommonData()。 Spring在创建对象之前不能注入字段值,因此在构造函数完成之前,Spring无法在commonDataService中连接。

而是使用initCommonData()注释@PostConstruct

public class BaseController {

    @Autowired
    private CommonDataService commonDataService;

    protected ModelAndView model; 

    @PostConstruct
    public void initCommonData(){
        this.model = new ModelAndView();
        this.model.addObject("headerData",commonDataService.getHeaderData());
        this.model.addObject("footerData",commonDataService.getFooterData());
    }
相关问题