我自己基于HttpServlet實(shí)現(xiàn)了一個(gè)簡單的MVC框架,大體的思路是在Servlet的init時(shí)將掃描到的 帶有注解的控制器和方法放到一個(gè)容器中,在請(qǐng)求過來時(shí)解析,通過反射調(diào)用具體的控制器類的方法。(請(qǐng)您不要笑話,可能我實(shí)現(xiàn)的比較簡陋,我還是一名在校生)在我實(shí)現(xiàn)了之后,想按照往常一樣將Service和DAO通過Spring注入,我嘗試在web.xml文件中加入ContextLoaderListener和context-param
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>simvc</servlet-name>
<servlet-class>com.nekolr.simvc.servlet.SimDispatcherServlet</servlet-class>
<!-- 這里是掃描的包 -->
<init-param>
<param-name>base-package</param-name>
<param-value>com.nekolr.ztree.controller</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>simvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
沒有報(bào)錯(cuò),但是在debug時(shí)看到,所有的注入都失敗了(null),我在想是不是我自己實(shí)現(xiàn)的MVC框架需要在init時(shí)做一些事情,但是又不知道該做什么,等了好久了,哪怕指引一個(gè)方向也好,謝謝各位!
經(jīng)提示,使用了手工注入的方式:
<bean id="ztreeDao" class="com.nekolr.ztree.dao.ZtreeDaoImpl"></bean>
<bean id="ztreeService" class="com.nekolr.ztree.service.ZtreeServiceImpl">
<property name="ztreeDao" ref="ztreeDao"></property>
</bean>
<bean id="ztreeController" class="com.nekolr.ztree.controller.ZtreeController">
<property name="ztreeService" ref="ztreeService"></property>
</bean>
但是還是失敗了(null)
繼續(xù)嘗試,在框架的入口Servlet的init方法里手工獲取bean:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Object ztreeService = context.getBean("ztreeService");
System.out.println(ztreeService);
打印成功,為什么在這里就可以獲取到,而注入反而不行呢?
感謝 @alexnevsky 大大的回答,讓我有了一個(gè)折中的方法:
實(shí)現(xiàn)ApplicationContextAware接口,創(chuàng)建一個(gè)工具類,用來獲取bean
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);
}
}
業(yè)務(wù)代碼:
@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<ZtreeNode> getData(){
List<ZtreeNode> list = ztreeService.getAll();
for(Iterator<ZtreeNode> iterator = list.iterator();iterator.hasNext();){
ZtreeNode node = iterator.next();
if(node.getParentid().equals(0L)){
node.setParent(true);
}else{
node.setParent(false);
}
}
return list;
}
}
但是感覺好別扭啊。。
經(jīng)過 @bugzy 大大的提醒,我明白了注入失敗的原因:
我的Controller實(shí)例并不是放在Spring容器當(dāng)中的(Spring應(yīng)該是在創(chuàng)建Controller實(shí)例時(shí)將Service注入了,連同DAO,同時(shí)要考慮注入順序)。在MVC框架中,我通過反射來創(chuàng)建Controller的實(shí)例,這和通過Spring獲取有本質(zhì)區(qū)別。但是框架本身的實(shí)現(xiàn)如此,我認(rèn)為一種方式就是我上面使用的,在Controller里手動(dòng)獲取Service,另一種方式就是想辦法在反射創(chuàng)建Controller時(shí),將需要注入的對(duì)象注入,但是目測(cè)不好處理。
2 回答

白衣染霜花
TA貢獻(xiàn)1796條經(jīng)驗(yàn) 獲得超10個(gè)贊
用spring就要在spring.xml中配置掃描包。servlet不是控制層嗎?通過參數(shù)值反射類?

開滿天機(jī)
TA貢獻(xiàn)1786條經(jīng)驗(yàn) 獲得超13個(gè)贊
“帶有注解的控制器和方法放到一個(gè)容器中”,我猜你大概自己實(shí)現(xiàn)了一個(gè)管理controller的容器,所以當(dāng)然注入失敗,你的controller必須放進(jìn)spring的bean容器中。
首先,你的controller必須加入 spring 的 bean 容器;
然后,你可以稍加改造你的dispatcher,掃描到自己定義的訪問路徑以及類方法后,從spring容器中取出對(duì)象執(zhí)行,不要用反射自己 newInstance.
Good Luck.
添加回答
舉報(bào)
0/150
提交
取消