Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Auto-cast Spring Beans

Is there a way to auto-cast Spring beans to the class defined in the application context XML? I'd like to avoid putting type information about the beans in 2 places.... in the xml configuration file and also in the code as a cast.

For instance, given this config file

<bean id="bean-name" class="SimpleSpringBean"  scope="prototype">
    <property name="myValue" value="simple value"></property>
</bean>

Can I call ApplicationContext.getBean("bean-name") in such a way as to avoid directly casting the return type to SimpleStringBean. I know I can also call ApplicationContext.getBean("bean-name", SimpleSpringBean.class) to avoid the cast itself, but I still have the type info in 2 places.

It seems that Spring can get the class info (ApplicationContext.getType) or by getting the type from the bean itself, but no way to automatically cast the type without programmer intervention.

like image 870
Vinnie Avatar asked May 01 '09 16:05

Vinnie


People also ask

What is the role of ApplicationContextAware in Spring?

As we know, the primary job of the ApplicationContext is to manage beans. As such, an application must provide the bean configuration to the ApplicationContext container. A Spring bean configuration consists of one or more bean definitions. In addition, Spring supports different ways of configuring beans.

How does BeanFactory work in Spring?

The BeanFactory is the actual container which instantiates, configures, and manages a number of beans. These beans typically collaborate with one another, and thus have dependencies between themselves.


2 Answers

I agree with Sii, you should avoid calling getBean as much as you can. Just wire your beans to classes that depends on them.

Still, if you have a single class that holds the application context, you can provide a wrapper generic method like the following:

class MyContextHolder{
    ApplicationContext appContext;
    ......
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String beanName)
    {
        return (T)appContext.getBean(beanName);
    }
}

Then you can call it without casting

MyClass mc = MyContextHolder.getBean("myClassBean");
like image 74
LiorH Avatar answered Sep 23 '22 00:09

LiorH


The answer is you shouldn't be using ApplicationContext.getBean() at all if it's possible, and bear with the one place you have to in the bootstrap code. (Generally, you should never need to use getBean() outside of your application's entry points.)

Also, what you're asking is likely impossible in the Java language at all. Casting is a compile-time feature, combined with a runtime check. The return type of getBean() simply must be known at compile time. Even if Spring can determine the type of an object, it can't change its own method signatures at runtime.

Another thing is that even if this were possible, the feature wouldn't be all that useful. Because Spring AOP is implemented using dynamic proxies, you nearly always want Spring to hand you an instance of an interface the bean implements (which could be an AOP proxy), not of the implementation class.

like image 41
millimoose Avatar answered Sep 24 '22 00:09

millimoose