Data Access/Integration Web
(JDBC, ORM, OXM, JMS) (WebSocket, Servlet, Web, Portlet)
Transactions |
\ /
AOP Aspects Instrumentation Messaging
|
Core Container
|
test
Each of module has their own jarfiles
- spring-core
- spring-beans
- spring-context
- spring-context-support
- spring-expression
- spring-aop
- spring-aspects
- spring-instrument
- spring-instrument-tomcat
- spring-jdbc
- spring-tx
- spring-orm
- spring-oxm
- spring-jms
- spring-web
- spring-webmvc
- spring-websocket
- spring-webmvc-portlet
- spring-test
Each of module has their own jarfiles
note: Spring 2.x comes with lib
folder contains (dependent library jarfiles), Spring 3.x ship without lib
folder.
Only one singleton class: Logger
.
Logger log = Logger.getLogger();
log.append()
log.debug()
log.warm()
log.info()
Objects define their dependencies only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned form a factory method. The container then injects those dependencies when it creates the bean.
- keywords:
- Factory Pattern: id always reference an object
- Reflection: inject values into fields
- Decoupling: decouple Data & Logic, actual value & bean structure.
org.springframework.beans
and org.springframework.context
are the basis for IoC container.
org.springframework.beans.factory.BeanFactory
: deprecatedorg.springframework.context.ApplicationContext
: represents the IoC container and is responsible for instantiating, configuring and assembling the objects.
POJOs -------------> IoC Container -> Fully configured system
config metadata ------^
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // src is the root folder
ApplicationContext context = new FileSystemXmlApplicationContext("file.xml"); // project folder is the root folder
Configuration metadata can be imported: File path is related to the definition file doing the importing.
<beans>
<import resource="<file xml>"/>
</beans>
ApplicationContext context = new AnnotationConfigApplicationContext(Configuration.class);
Bean bean = context.getBean("bean name", bean.class);
<bean id="ID" class="package.class_name>" scope="">
<property name="field_name" value="" />
<property name="field_name">
<value>??</value>
</property>
<property name="field_name" ref="bean_id" />
</bean>
note: the class may not have a field that matches exactly the property name, but it must has a setter matching that property name (public void set<field>
).
<bean id="ID" class="package.class_name>" scope="">
<constructor-arg type="" value=""/>
<constructor-arg>
<ref bean="bean_id" />
</constructor-arg>
<constructor-arg index="0" value=""/>
<!-- use with @ConstructorProperties({name1, name2}) for the constructor -->
<constructor-arg name="field_name" value=""/>
</bean>
- Difference between setter injection and constructor injection:
- CI is good for mandatory dependencies and SI for optional dependencies.
- Partial dependency: setter injection only
- If both injection have be defined, IoC container will use the setter injection.
- Setter injection can make update to beans without create a new one.
- What is method injection?
Pre-instantiation is desirable, because errors in the configuration or surrounding environment are discovered immediately. However, we can tell the IoC container to create a bean instance when it is first requested(lazy-initialized)
BeanFactory (all lazy-initialized) (mobile application)
^
|
ApplicationContext (not lazy-initialized) : all beans are created after `new FileSystemXmlApplicationContet("<config.xml>")` (enterprise application)
- We control lazy loading feature for both of them by setting
<bean lazy-init="default|true|false"/>
. - Container level:
<beans default-lazy-init="true"/>
An interface provides control of two behaviors of bean initialization.
postProcessBeforeInitialization
: before the bean is initialized.postProcessAfterInitializtion
: after the bean is initialized.
Automatically injection other beans inside current bean implicitly (usually ref
is better)
- no: must be defined via a
ref
element. - byName: use field name to match other beans
- byType: user field type to match other beans (but this cannot handle the situation that different beans have same type or subtype)
- constructor: analogous to byType, but applies to constructor arguments.
- autodetect (spring 2.x, deprecated)
- excluding a bean from autowiring:
<bean autowire-candidate="false"/>
. - container level limitation: `.
Inject a method: dynamically override the implementation of a method.
- the method to be injected requires a signature of the following form:
<public|protected> [abstract] <return-type> theMethodName(no-arguments);
s
By default Spring uses reflection to bypass private constructor and instantiate an new object. Therefore, a singleton in Spring will return different objects under scopes except singleton.
- We HAVE to specify
factory-method="getInstance"
to force Spring get a singleton object in all scopes. - Without
factory-method
, even in singleton scope, we will have two objects from a singleton. One is from reflection API, the other one is fromgetInstance()
.
- singleton (default): single instance per container (each definition).
- prototype (shallow copy): any number of instances.
Blow scopes are only available for a web-aware Spring ApplicationContext
implementation.
3. request: each HTTP request has its own instance of a bean.
4. session: each HTTP Session
has its own instance of a bean.
5. global session: each global HTTP Session
has its own instance of a bean. Typically only valid when used in a portlet context.
6. application: each ServletContext
has its own instance of a bean.
- Use the prototype for all stateful beans and the singleton for stateless beans.
- Spring does not manage the destruction lifecycle of a prototype bean.
- request, session, global session, application scopes work with Spring Web MVC
DispatcherServlet
orDispatcherPortlet
without special setup. - For request, session, global session scoped beans, we must inject an AOP proxy in place of them.
- Implement
o.s.beans.factory.config.Scope
- Register the scope with a
o.s.beans.factory.config.CustomScopeConfigurer
public interface Scope {
// map-like lookup of beans in a given scope
Object get(String name, ObjectFactory<?> objectFactory);
Object remove(String name);
void registerDestructionCallback(String name, Runnable callback);
// well known beans like the HttpServletRequest 'request' for 'request' scope
Object resolveContextualObject(String key);
// returns an ID that can be correlated to an object stored in a system backing the scope
String getConversationId();
}
- Purpose of AOP: Build dependency among separate classes
- Key concepts:
- Advice (what)
- Pointcut (where)
- Advisor = Advice + Pointcut
- Proxy Pattern
An interface used to get beans outside Spring container.
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
DI with expression
example:
// 1
@Value("#{ otherBean.getValue() }")
private int aValue;
// 2
@Value("#{ systemProperties['user.home'] }")
private string userHome
Group beans into profiles, and load them based on a run-time argument -Dspring.profiles.active=<profile name>
example
@Configuration
@Profile("config1")
public class Config1 { ... }
@Configuration
@Profile("config2")
public class Config2 { ... }
@Configuration
@Import("Config1.class, Config2.class")
public class Config3 {
// only one of Config1/2 will be imported based on run-time the arg.
}
CMP: Container-Managed Persistence BMP: Bean-Managed Persistence
BeginTx
BeginTx
...
Commit
...
BeginTx
Commit
Commit
- Reqiured:
BT BT
#do1 #do1
BT #do2
#do2 => #do3
CT CT
#do3
CT
Any inner transaction fails will rollback the outer transaction (Default behavior of propagation)
- method driven method return ModelAndView -> add prefix, sufferfix to generate the view.
- The method can return
- Model(data) and View(page) (return a
ModelAndView
object) - View only (return a String as the view name)
- Model only (use
@ResponseBody
)
- Model(data) and View(page) (return a
@Component
/ | \
@Controller @Service @Repository (DAO)
- Proxy Pattern
- Business Delegate
- filter
- listener & context-param
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-security.xml
</param-value>
</context-param>
- By default, it uses
applicationContext.xml
- config file
- intercept-url (pattern to apply spring security)
Initialize a collection.
<util:list id="<bean>">
<bean class="<class>">
<property name="" value="" />
</bean>
<util:list>
@EnableScheduling
public class Config {
@Bean
public TaskScheduler concurrentTaskScheduler() {
ConcurrentTaskScheduler concurrentTaskScheduler = new ConcurrentTaskScheduler();
concurrentTaskScheduler.setScheduledExecutor(Executors.newScheduledThreadPool(10));
return concurrentTaskScheduler;
}
@Component
public static class ScheduledBean {
@Scheduled(cron = "*/10 * * * * *")
public void runMeByACronExpression() throws Throwable {
System.out.println("runMeByACronExpression@ " + new Date());
}
@Scheduled(fixedRate = 15 * 1000)
public void runMeByAFixedRate() throws Throwable {
System.out.println("runMeByAFixedRate@ " + new Date());
}
@Scheduled(fixedDelay = 20 * 1000)
public void runMeByAFixedDelay() throws Throwable {
System.out.println("runMeByAFixedDelay@ " + new Date());
}
}
}
RowMapper<Customer> customerRowMapper = new RowMapper<Customer>() {
public Customer mapRow(ResultSet resultSet, int i) throws SQLException {
long id = resultSet.getInt("id");
String firstName = resultSet.getString("first_name");
String lastName = resultSet.getString("last_name");
return new Customer(id, firstName, lastName);
}
};
Long id = 23L;
Collection<Customer> customers = jdbcTemplate.queryForObject(
"select * from customers where id = ?", customerRowMapper, id);