Human Being
Human Being

Reputation: 8387

ways to inject a object of a class in spring controller?

I need to inject a object of a java class in spring controller through applicaionContext.xml. My controller will be ,

@Controller
public class SpringController{

private MyClass obj;

}

I know I can do it with @Autowired annotation.

Is this really good to create a object for a controller through applicaionContext.xml ? Also can I inject a object of a class in controller using the <property> tag inside a <bean> tag ?

Is this really possible ? or please forgive me if it is a stupid question.

I need to know the possible ways for how to inject a object of a class in Spring controller ?

Upvotes: 3

Views: 8295

Answers (4)

a.valchev
a.valchev

Reputation: 388

I ran into such problem. I was getting "Ambiguous mapping found". (I use xml configuration as well and i am injecting a bean into my controller) Then looking at my console i realized that my controller was being instantiated twice. In more detailed look i noticed that my annotation

@Controller(value = "aController")

(Note value = "aController")

was different from my xml configuration where i was instatiating the same controller with different bean id

<bean id="aControleRRRRR" class="package.ControllerClassName"
    p:property-ref="beanToInject" />

(Note id="aControleRRRRR")

So in conclusion your @Controller name (value = "aController") needs to be exactly the same as the name you give in the XML configuration (id="aControleRRRRR"), so that Spring can manage to distinct that they refer to the same bean (instance)

Hope this helps

Upvotes: 0

beinghuman
beinghuman

Reputation: 2146

If you want to inject an object in a controller and you particularly want to you use xml,then instead of component scanning of Controller you should create a bean of the controller class of singleton scope in the application context. Your controller class need not be annotated with @Controller.

you then have to you extend some Controller also like AbstractCommandController, AbstractController, AbstractFormController, AbstractWizardFormController, BaseCommandController, CancellableFormController, MultiActionController SimpleFormController, UrlFilenameViewController

Now to inject a particular object you can use Either Constructor and Setter based injection. or you can use Autowring by name or type to auto inject the object. Make sure that you have also declared the bean of that object also in Application Context.

After a DispatcherServlet has received a request and has done its work to resolve locales, themes and suchlike, it then tries to resolve a Controller, using a HandlerMapping. When a Controller has been found to handle the request, the handleRequest method of the located Controller will be invoked; the located Controller is then responsible for handling the actual request and - if applicable - returning an appropriate ModelAndView.

Thats it.

Upvotes: 1

erencan
erencan

Reputation: 3763

Actually, injection with xml and annotation is same behind the scene. Xml is old fashion while annotations are newer.

Basically, there are 2 types of injection types.

byName

Autowiring by property name. Spring container looks at the properties of the beans on which autowire attribute is set to byName in the XML configuration file. It then tries to match and wire its properties with the beans defined by the same names in the configuration file.

You can give explicit names to beans both with xml and annotation.

@Service("BeanName")
@Component("BeanName")
@Controller("BeanName")

<bean name="BeanName" class="someclass"></bean>

and inject beans by using @Qualifier annotation.

@Autowired
 @Qualifier("BeanName")

and with xml

<bean id="MyBean2" class="MyBean2 class">
<property name="Property of MyBean2 which refers to injecting bean" ref="BeanName" />
</bean>

byType

Autowiring by property datatype. Spring container looks at the properties of the beans on which autowire attribute is set to byType in the XML configuration file. It then tries to match and wire a property if its type matches with exactly one of the beans name in configuration file. If more than one such beans exists, a fatal exception is thrown.

Default auto wiring mode is byType, so spring will look for matching type in auto wiring. However, older versions of Spring has default behavior none on injection. If you want to inject byType using xml, you should tell spring contaioner explicitly.

For example MyBean2 has a reference to MyBean, by setting autowired attribute to byType it handles injection automatically.

<bean id="MyBean" class="MyBean class">
<property name="Property of MyBean2 which refers to injecting bean" ref="BeanName" />
</bean>

<bean id="MyBean2" class="MyBean2 class" 
      autowire="byType">      
 </bean>

It also depends on where the injection take place in your code. There are 2 types, setter getter injection and constructor injection.

Note : There is no difference in @Controller since they are already in spring context.

See also

Spring Beans Auto wiring

Upvotes: 1

Debojit Saikia
Debojit Saikia

Reputation: 10632

You can of course use @Autowired annotation to autowire the relationships, which can reduce the need to define the properties and constructor arguments for the controller in your applicationContext.xml file. And also to add a dependency to a class, you don't need to modify the configuration files.

But it has some disadvantages too, like if you use @Autowired, there will not be any explicit documentation for the wiring details between Spring managed beans. And to know the relationships between the beans, you have to go through your managed beans. But, if you use configuration files to define the relationships, the relationship details can be found in one place.

You can inject an object of a class into your controller through your applicaionContext.xml as below:

Constructor based injection:

@Controller
public class SpringController{

private MyClass obj;

public SpringController(MyClass obj){
this.obj=obj;
}
}

<bean id="myClassImpl" class="x.y.z.MyClassImpl"></bean>

<bean id="springController" class="x.y.z.web.controllers.SpringController">
    <constructor-arg ref="myClassImpl"></constructor-arg>
</bean>

Setter based injection:

@Controller
public class SpringController{

private MyClass obj;

public void setObj(MyClass obj){
this.obj=obj;
}
public MyClass getObj(){
return obj;
}
}

<bean id="myClassImpl" class="x.y.z.MyClassImpl"></bean>

<bean id="springController" class="x.y.z.web.controllers.SpringController">
    <property name="obj" ref="myClassImpl"></property>
</bean>

Upvotes: 3

Related Questions