作者:carefulff | 来源:互联网 | 2023-10-11 09:30
我自己基于HttpServlet实现了一个简单的MVC框架,大体的思路是在Servlet的init时将扫描到的带有注解的控制器和方法放到一个容器中,在请求过来时解析,通过
我自己基于HttpServlet实现了一个简单的MVC框架,大体的思路是在Servlet的init时将扫描到的
带有注解的控制器和方法放到一个容器中,在请求过来时解析,通过反射调用具体的控制器类的方法。
(请您不要笑话,可能我实现的比较简陋,我还是一名在校生)
在我实现了之后,想按照往常一样将Service和DAO通过Spring注入,我尝试在web.xml文件中加入
ContextLoaderListener和context-param
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
/WEB-INF/classes/applicationContext.xml
simvc
com.nekolr.simvc.servlet.SimDispatcherServlet
base-package
com.nekolr.ztree.controller
simvc
*.do
|
没有报错,但是在debug时看到,所有的注入都失败了(null),我在想是不是我自己实现的MVC框架需要在init时做一些事情,但是又不知道该做什么,等了好久了,哪怕指引一个方向也好,谢谢各位!
经提示,使用了手工注入的方式:
但是还是失败了(null)
继续尝试,在框架的入口Servlet的init方法里手工获取bean:
1 2 3
| ApplicationContext cOntext= new ClassPathXmlApplicationContext("applicationContext.xml");
Object ztreeService = context.getBean("ztreeService");
System.out.println(ztreeService); |
打印成功,为什么在这里就可以获取到,而注入反而不行呢?
感谢 @alexnevsky 大大的回答,让我有了一个折中的方法:
实现ApplicationContextAware接口,创建一个工具类,用来获取bean
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class AppUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
cOntext= applicationContext;
}
public static Object getBean(String id){
return context.getBean(id);
}
} |
业务代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @Controller
@RequestMapping(value = "/ztree")
public class ZtreeController {
private ZtreeService ztreeService = (ZtreeService) AppUtil.getBean("ztreeService");
@RequestMapping(value = "/index.do", method = RequestMethod.GET)
public String index(){
return "index";
}
@RequestMapping(value = "/getData.do", method = RequestMethod.GET)
@ResponseBody
public List getData(){
List list = ztreeService.getAll();
for(Iterator iterator = list.iterator();iterator.hasNext();){
ZtreeNode node = iterator.next();
if(node.getParentid().equals(0L)){
node.setParent(true);
}else{
node.setParent(false);
}
}
return list;
}
} |
但是感觉好别扭啊。。
经过 @bugzy 大大的提醒,我明白了注入失败的原因:
我的Controller实例并不是放在Spring容器当中的(Spring应该是在创建Controller实例时将Service注入了,连同DAO,同时要考虑注入顺序)。在MVC框架中,我通过反射来创建Controller的实例,这和通过Spring获取有本质区别。但是框架本身的实现如此,我认为一种方式就是我上面使用的,在Controller里手动获取Service,另一种方式就是想办法在反射创建Controller时,将需要注入的对象注入,但是目测不好处理。