开发者

How do I use polymorphism with Spring Beans?

Here is the premise for what I'm doing:

- Use a simple servlet to get page requests.

- Get a page id from the request to determine which page i'm on.

- Define the controllers in a beans xml config.

- Use the bean definition to determine which page controller class to use. - All of these page controllers extends CORE.Controllers.PageController class.

Here is what I am trying to do, but failing. I'm trying to load the page controller class (PersonController, which was determined from the beans) into the PageController variable. What you will see in my code sample is that I'm casting it into the PageController class. That doesn't work.

How do I get my PersonController object from the bean factory using polymorphism, into my variable?

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- -->
<bean id="home" name="home" class="CORE.Controllers.HomeController" />
<bean id="person" name="person" class="CORE.Controllers.PersonController" />

<!-- Property Management -->
<bean id="propertyEvaluator" class="CORE.Controllers.PropertyManagement.PropertyEvaluator" />
</beans>

The class is here in part:

String pageId = "home";
    if (request.getParameter("PID") != null)
    {
        pageId = request.getParameter("PID");
    }

    response.setContentType("text/html; charset=UTF-8"); // Set content type for HTML.
    PrintWriter out = response.getWriter(); // Output goes to the response PrintWriter.
    try
    {
        TransformerFactory tFactory = TransformerFactory.newInstance();
        String ctx = getServletContext().getRealPath("") + FS; //get the real path for xml and xsl files.

        BeanFactory pageFactory = new XmlBeanFactory(new FileSystemResource(ctx+"WEB-INF/page-cfg.xml"));
        PageMapping pageMap = (PageMapping) pageFactory.getBean("pageMapping");
        Page page = pageMap.getPageById(pageId);

        BeanFactory controllerFactory = new XmlBeanFactory(new FileSystemResource(ctx+"WEB-INF/controller-cfg.xml"));
        PageController controller = (PageController) controllerFactory.getBean(page.getController开发者_如何转开发Name());
        controller.setRequest(request);


Thanks for the update. I think I understand now - you want to avoid the cast to PageController.

Replace

PageController controller = (PageController)controllerFactory
    .getBean(page.getControllerName());

with

PageController controller = controllerFactory
    .getBean(page.getControllerName(), PageController.class);

Spring allows you to parameterize the getBean call with the type of the expected bean. In terms of implmentation "under the hood" it's still a cast, and you'll get a ClassCastException if the named bean doesn't correspond to the requested type, but at least now the compiler is handling this via generics.


In Spring, if we use JDK proxy (as @mdma corrected below), we can't cast an object to a concrete class instance, we're only able to cast it to in interface instance. In this case, you need to change PageController to an interface and have an implementation for it, named PageControllerImpl and declare it in you controller-cfg.xml.

If CGLIB is used, your code might ok.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜