What Is A Spring Bean?: Org - Springframework.Beans Org - Springframework.Context Beanfactory Applicationcontext Beanfactory

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 6

What is a Spring Bean?

In Spring, the objects that form the backbone of your application and that are managed by the
Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and
otherwise managed by a Spring IoC (Inversion of Control) container.

IoC is also known as dependency injection (DI). It is a process whereby objects define their
dependencies, that is, the other objects they work with. The container then injects those
dependencies when it creates the bean.

The org.springframework.beans and org.springframework.context packages are the basis


for Spring Framework's IoC container. The BeanFactory interface provides an advanced
configuration mechanism capable of managing any type of object. ApplicationContext is a
sub-interface of BeanFactory.

The interface org.springframework.context.ApplicationContext represents the Spring IoC


container and is responsible for instantiating, configuring, and assembling the aforementioned
beans. The container gets its instructions on what objects to instantiate, configure, and assemble
by reading configuration metadata. The configuration metadata is represented in XML, Java
annotations, or Java code. It allows you to express the objects that compose your application and
the rich interdependencies between such objects.

In most application scenarios, explicit user code is not required to instantiate one or more
instances of a Spring IoC container. For example, in a web application scenario web.xml file of
the application will typically suffice.

The Spring IoC container consumes a form of configuration metadata; this configuration
metadata represents how you as an application developer tell the Spring container to instantiate,
configure, and assemble the objects in your application.

Starting with Spring 3.0, many features provided by the Spring JavaConfig project became part
of the core Spring Framework. Thus, you can define beans external to your application classes
by using Java rather than XML files. For this use the @Configuration, @Bean, @Import and
@DependsOn annotations.

A typical enterprise application does not consist of a single object (or bean in the Spring
parlance). Even the simplest application has a few objects that work together to present what the
end-user sees as a coherent application.

Code is cleaner with the DI principle and decoupling is more effective when objects are provided
with their dependencies. The object does not look up its dependencies and does not know the
location or class of the dependencies. As such, your classes become easier to test, when the
dependencies are on interfaces or abstract base classes, which allow for stub or mock
implementations to be used in unit tests.

In Spring 2.0 and later, the @Repository annotation is a marker for any class that fulfills the role
or stereotype (also known as Data Access Object or DAO) of a repository.
Spring 2.5 introduces further stereotype annotations: @Component, @Service, and
@Controller. @Component is a generic stereotype for any Spring-managed component.
@Repository, @Service, and @Controller are specializations of @Component for more
specific use cases, for example, in the persistence, service, and presentation layers, respectively.

Spring components can also contribute bean definition metadata to the container. You do this
with the same @Bean annotation used to define bean metadata within @Configuration annotated
classes. Here is a simple example:

@Component
public class FactoryMethodComponent {

@Bean @Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}

public void doWork() {


// Component method implementation omitted
}
}

This class is a Spring component that has application-specific code contained in its doWork()
method. However, it also contributes a bean definition that has a factory method referring to the
method publicInstance(). The @Bean annotation identifies the factory method and other bean
definition properties, such as a qualifier value through the @Qualifier annotation. Other method
level annotations that can be specified are @Scope, @Lazy, and custom qualifier annotations.

@Bean is a method-level annotation and a direct analog of the XML <bean/> element. The
annotation supports some of the attributes offered by <bean/>, such as: init-method, destroy-
method, autowiring and name.

You can use the @Bean annotation in a @Configuration-annotated or in a @Component-


annotated class.

To declare a bean, simply annotate a method with the @Bean annotation. You use this method to
register a bean definition within an ApplicationContext of the type specified as the method's
return value. By default, the bean name will be the same as the method name. The following is a
simple example of a @Bean method declaration:

@Configuration
public class AppConfig {

@Bean
public TransferService transferService() {
return new TransferServiceImpl();
}

}
The preceding configuration is exactly equivalent to the following Spring XML:

<beans>
<bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>

Any classes defined with the @Bean annotation support the regular lifecycle callbacks and can
use the @PostConstruct and @PreDestroy annotations.

The @Bean annotation supports specifying arbitrary initialization and destruction callback
methods, much like Spring XML's init-method and destroy-method attributes on the bean
element:

public class Foo {


public void init() {
// initialization logic
}
}

public class Bar {


public void cleanup() {
// destruction logic
}
}

@Configuration
public class AppConfig {
@Bean(initMethod = "init")
public Foo foo() {
return new Foo();
}
@Bean(destroyMethod = "cleanup")
public Bar bar() {
return new Bar();
}
}

Of course, in the case of Foo above, it would be equally as valid to call the init() method
directly during construction:

@Configuration
public class AppConfig {
@Bean
public Foo foo() {
Foo foo = new Foo();
foo.init();
return foo;
}

// ...
}
Request, session, and global session scopes
The request, session, and global session scopes are only available if you use a web-aware
Spring ApplicationContext implementation (such as XmlWebApplicationContext). If you
use these scopes with regular Spring IoC containers such as the
ClassPathXmlApplicationContext, you get an IllegalStateException complaining about
an unknown bean scope.

If you access scoped beans within Spring Web MVC, in effect, within a request that is processed
by the Spring DispatcherServlet, or DispatcherPortlet, then no special setup is necessary:
DispatcherServlet and DispatcherPortlet already expose all relevant state.

If you use a Servlet 2.4+ web container, with requests processed outside of Spring's
DispatcherServlet (for example, when using JSF or Struts), you need to add the following
javax.servlet.ServletRequestListener to the declarations in your web applications
web.xml file:

<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>

Consider the following bean definition:

<bean id="loginAction" class="com.foo.LoginAction" scope="request"/>

The Spring container creates a new instance of the LoginAction bean by using the loginAction
bean definition for each and every HTTP request. That is, the loginAction bean is scoped at the
HTTP request level. You can change the internal state of the instance that is created as much as
you want, because other instances created from the same loginAction bean definition will not
see these changes in state; they are particular to an individual request. When the request
completes processing, the bean that is scoped to the request is discarded.

Lifecycle callbacks
To interact with the container's management of the bean lifecycle, you can implement the Spring
InitializingBean and DisposableBean interfaces. The container calls
afterPropertiesSet() for the former and destroy() for the latter to allow the bean to
perform certain actions upon initialization and destruction of your beans.

Internally, the Spring Framework uses BeanPostProcessor implementations to process any


callback interfaces it can find and call the appropriate methods.

The InitializingBean interface specifies a single method:


void afterPropertiesSet() throws Exception;

It is recommended that you do not use the InitializingBean interface because it unnecessarily
couples the code to Spring. Alternatively, use the @PostConstruct annotation or specify a POJO
initialization method. In the case of XML-based configuration metadata, you use the init-
method attribute to specify the name of the method that has a void no-argument signature. For
example, the following definition:

<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>

public class ExampleBean {

public void init() {


// do some initialization work
}
}

...is exactly the same as...

<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>

public class AnotherExampleBean implements InitializingBean {

public void afterPropertiesSet() {


// do some initialization work
}
}

Dependency Injection with @Inject and @Named


Instead of @Autowired, @javax.inject.Inject may be used as follows:

import javax.inject.Inject;

public class SimpleMovieLister {

private MovieFinder movieFinder;

@Inject
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}

As with @Autowired, it is possible to use @Inject at the class-level, field-level, method-level


and constructor-argument level. If you would like to use a qualified name for the dependency
that should be injected, you should use the @Named annotation.

Instead of @Component, @javax.inject.Named may be used as follows:

import javax.inject.Inject;
import javax.inject.Named;
@Named("movieListener")
public class SimpleMovieLister {

private MovieFinder movieFinder;

@Inject
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}

You might also like