Spring Bean
Bean Scope
Spring defines following bean scopes:
- Singleton
- Prototype 每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例
- Session
- Request
By default, spring bean is singleton.
Define scope
@Scope( ConfigurableBeanFactory. SCOPE_ PROTOTYPE)
or @Scope("prototype")
, former is better, because it is safer and
not easy be wrong.
or <bean id="..." class="..." scope="prototype" />
Session
and Request
scopes are in WebApplicationContext
Config Bean
There are three approaches to config bean in spring:
- Implict
- Explict by java
- Explict by xml
Implict
- Create a config class, add
@Configuration
and@ComponnetScan
for it,
@Configuration
@ComponentScan(basePackages={"packageA", "packageB"})
public class CarConfig {
}
Component scan only scans @Component
By default, spring only scan the classes whose package is the same as config class’.
Alternatively, <context:component-scan base-package="packageA"></context:component-scan>
can be used in spring
context xml file.
- Create bean, add
@Component
for it
@Component("suv")
public class SUV implements Car {
@Override
public void run() {
System.out.println("SUV is running!");
}
}
@Component, @Controller, @Service and @Repository
-
With these annotation, spring is able to import beans into the container so that developer don’t have to define them explicitly in xml after enabling component scan. These annotations are called stereotype annotation as well.
-
@Controller
,@Service
and@Repository
are annotaed with@Component
, e.g.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
....
}
-
@Component is a general purpose stereotype annotation, is equal to
<bean>
of xml, while @Controller, @Service and @Repository are specialized annotation of @Component, they are equal @Component + some more special functionalityBy annotating class with @Controller, @Service or @Repository, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts.
-
@Repository is used for DAO layer, it provides additional benefits : makes the unchecked exceptions(thrown from DAO methods) eligible for translation into spring
DataAccessException
And for this, we’re provided with PersistenceExceptionTranslationPostProcessor, that we are required to add in our Spring’s application context like this:
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
This bean post processor adds an advisor to any bean that’s annotated with @Repository so that any platform-specific exceptions are
caught and then rethrown as one of Spring’s unchecked data access exceptions. -
@Service is uesed in service layer
-
@Controller indicates this class is a controller, like spring web mvc controller class
A good practice is using @Controller, @Service and @Repository at most of the time, @Component should be used when your class does not fall into either of controller, service or DAO
When component scan is declared, developer no longer need to declare context:annotation-config
, because autowiring is implicitly
enabled in this case.
Always use these annotations over concrete classes rather than interfaces
Explicit by java
Create a config class, add @Configuration
for it,
then define a method to return a bean instance and add @Bean
for this method
@Configuration
public class CarConfig {
@Bean
public Car car() {
return new SUV();
}
}
public class SUV implements Car {
@Override
public void run() {
System.out.println("explit java config suv");
}
}
For above two methods, the web.xml is suppose to be
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>example.my.spring.config.CarConfig</param-value>
</context-param>
Explicit by xml
- Define POJO
- Create a spring context xml file and define beans in it
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan base-package="example.my.model"></context:component-scan>
<context:annotation-config/>
<tx:annotation-driven />
<bean id="service" class="example.my.service.MyService" >
<property name="property-name-of-bean" ref="another-bean-id" />
<property name="property-name-of-bean" value="property-value" />
</bean>
- the web.xml should be
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
@Autowired
The @Autowired
annotation can be used to autowire bean on the setter method, constructor, a property or methods.
-
@Autowired
is placed on setter methods to get rid of the<property>
element in XML configuration file. -
Get rid of the setter methods when it is on properties.
-
Annotate it on constructors indicates that the constructor should be autowired when creating the bean, even if no
<constructor-arg>
elements are used while configuring the bean in XML file.
required attribute
By default, the @Autowired
annotation implies the dependency is required.
However, developer can use @Autowired(required=false)
to turn off this feature.
autowired in multiple implementations
@Qualifier
can be used to indicate using which concerete implementation class.
@Autowired
@Qualifier("implementation1")
private MyInterface myInterface
or
@Resource(name="implementation1")
private MyInterface myInterface
@Inject
is similar @Autowired
just it is JSR-330 standard not Spring-specific.
@Resource
is part of the JSR-250.