我想为所有控制器调用一个公共服务,以获取一个带有一些常见对象的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。
答案 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());
}