Sei sulla pagina 1di 18

INTRO current version (5 relased on july2016, 4 on dec2013)

*****

spring modules 20 can be categorized to 6 areas.

1) spring core

2) AOP

3) Data Access / Integration

4) WEB

5) TEST

6) Instrument

1) Spring core - majorly about Dependency injection and functionalities on which other modules rely on.

2) AOP - cross cutting concerns of applications are called aspects. ( eg security, logging, transaction
mgmt )

simple offer from spring -- Spring AOP

Heavy track offer -- AspectJ

Spring supports declarative transaction management through AOP.

3) Data Access / Integration

supports JDBC, ORM (Object Relational Mapping), OXM (object XML Mapping) , JMS (Java Message
Service)

supports JDBC - manages connections and connection pools

ORM - supports Hibernate, iBATIS ( apache discontinued on 2010 ), JDO (java Data Objects) and JPA
(Java Persistence API)
OXM (object XML Mapping) - XML mapping supported for Castor, JAXB (Java Arch for XML Binding), JiBX,
XMLBeans, XStream.

JMS (Java Message Service) - allows to produce & consume messages.

JTA -- supports programming and declarative transaction management.

4) WEB

provides easy multipart upload and web-based remoting.

provides own servlet MVC and portlet MVC.

supports and integrates with other single (web ) tier frameworks like Structs, JavaServerFaces, Velocity,
FreeeMaker, JavaServer Pages.

5) TEST.

supports JUnit and TestNG frameworks.

DI

**

**

we need to have a dependency UML Like

AccountService --> AccountDAO (interface ) --> DataSource (interface)

NOTE: Data source can be DB/csv. DAO is jdbc or orm.

public class AccountService

private AccountDao accountDao;

public AccountService() {}
public void setAccountDao(AccountDao accountDao)

this.accountDao = accountDao;

import javax.sql.DataSource;

import com.springinpractice.ch01.dao.AccountDao;

public class JdbcAccountDao implements AccountDao

private DataSource dataSource;

public JdbcAccountDao() {}

public void setDataSource(DataSource dataSource)

this.dataSource = dataSource;

SPRING configuration file (usally named ** application-Context.xml, src/main/resources directory).

<?xml version="1.0" encoding="UTF-8"?>

<!-- Source project: sip01, branch: 03 (Maven Project) -->

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql://localhost:3306/springbook?autoReconnect=true"/>

<property name="username" value="someusername"/>

<property name="password" value="somepassword"/>

</bean>

<bean id="accountDao" class="com.springinpractice.ch01.dao.jdbc.JdbcAccountDao">

<property name="dataSource" ref="dataSource"/>

</bean>

<bean id="accountService" class="com.springinpractice.ch01.service.AccountService">

<property name="accountDao" ref="accountDao"/>

</bean>

</beans>

wrong ways:

importing org.apache.commons.dbcp.BasicDataSource in JdbcAccountDao class and instatiating


dataSource.

This way might seem correct but its not.

error 1) AccountService --> AccountDAO (interface ) --> DataSource (interface) is expected

But this way will provide you AccountService --> AccountDAO (interface ) __ BasicDataSource (concrete
relationship). DAO and BasicDataSource got coupled.

So in a way the tester can mock up with other datasources only by editing the touching the code.

you can say you will do by having interface DataSource and using a config file.
But in that way also the properties needed and parsing of config creates configuration coupling between
the DAO and datasource as the class will have congifuration

and new BasicDataSource statement along with import org.apache.commons.dbcp.BasicDataSource


statement.

AccountService --> AccountDAO (interface ) ---------configures----------> (Basic not sure of it) DataSource

Sample PROJECT

**************

AccountService --> AccountDAO (interface )


---> DataSource (interface)

step1)
define domain objects

step2) define DAO (interface only method sign)

step3) create concrete DAO ( has Datasource property)

Note: we need to write setters explicitly (avoided in spring boot by annotation , spring will use these
setters for DI, setter DI. JavaBeans programming model suggested the setters first , spring uses it).

Concrete DAO will instantiate Domain objects from the raw data it got from Data source through the
datasource interface exposed methods.

step 4) service will use the domain objects and code business logic.

application-Context.xml can be broken down into multiple parts. DAO configs in one file etc.

***********************

***********************

Spring ships with different schemas for configuring its different pieces of functionality, such as AOP and
transaction management.

For now, we declare the beans in the sample config file


beans xmlns="http://www.springframework.org/schema/beans"

<xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

Every bean has 1) ID -- to refer between beans. 2) class --FQDN

and properties will be having name and value/ref attribute.( for classes use ref and for resources use
value )

SPRING uses REFLECTION to instantiate the classes

AccountService --> AccountDAO (interface )


---> DataSource (interface)

--> ENTITY <--

FINALLY we have the client class ( a console app)

parts of that

1) ApplicationContext ( a) ClassPathXmlApplicationContext etc ) , a class which assist to call any bean


from application-context.xml file.

import org.springframework.context.ApplicationContext;

The ApplicationContext interface and its implementations are the gateway into the beans through
Spring.

They essentially make up a sophisticated implementation of the factory pattern.


In order for the factory to instantiate beans, the beans must have a no-argument constructor. There are
ways to initalize classes with named parameters.

import java.util.List;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.springinpractice.ch01.model.Account;

import com.springinpractice.ch01.service.AccountService;

public class ConsoleApp

public static void main(String[] args) throws Exception

ApplicationContext appCtx =

new
ClassPathXmlApplicationContext("applicationContext.xml");

AccountService accountService =

(AccountService)appCtx.getBean("accountService");

List<Account> delinquentAccounts = accountService

.findDeliquentAccounts();

for (Account a : delinquentAccounts)

System.out.println(a.getAccountNo());

1.4) Beans namespace.

************************
************************

<xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

The beans namespace is the most fundamental and deals with DI;

it provides a way to define beans and wire dependency relationships between them. To create a
configuration file that uses the beans namespace, you create an XML document and reference

the schema:

1.4.1)CONSTRUCTOR or SETTER can be used for injection

*****************************************************

We have seen setter DI already. see the constructor DI

<bean id="accountService" class="com.springinpractice.ch01.service.AccountService">

<constructor-arg ref="accountDao"/>

</bean>

public AccountService(AccountDao accountDao)

this.accountDao = accountDao;

NOTE: Property values are set to strings. If the parameters has different type, spring will convert to the
type needed.
PropertyPlaceholderConfigurer

*****************************

allows you to parametrize the application-context.xml.

declare it as a bean

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="location" value="springbook.properties"/>

</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

<property name="driverClassName" value="${dataSourcefile.driverClassName}"/>

<property name="url" value="${dataSourcefile.url}"/>

<property name="username" value="${dataSourcefile.username}"/>

<property name="password" value="${dataSourcefile.password}"/>

</bean>

And the config file looks like one below ( usually put up at src/main/resources, and since that is included
in classpath, will be loaded without errors)

springbook.properties):

dataSourcefile.driverClassName=com.mysql.jdbc.Driver

dataSourcefile.url=jdbc:mysql://localhost:3306/springbook?autoReconnect=true

dataSourcefile.username=root

dataSourcefile.password=secret

If you want to add some other path (like useraccount home )

<property name="location" value="file:${user.home}/springbook.properties"/>


1.4.2) Bean scopes

******************

define how the instiantiation and destruction of beans should happen as requested from containers.

5 ways:

<bean id="accountDao" class="com.springinpractice.ch01.dao.jdbc.JdbcAccountDao"

scope="singleton|prototype|request|session|globalSession"/>

Singleton scope ( DEFAULT one , cached and shared )

***************

***************

not equivalent to singleton design pattern. where one class for a classloader.

Declaring a singleton bean in Spring ensures that only one instance exists on a per-container basis

As long as resources are thread-safe—meaning they’re synchronized, immutable, have no state, or have
fields where any of the previous criteria are strictly met

—you can safely declare them with singleton scope to eliminate the overhead of creating them each
time they’re requested.

For example, singleton (default ) services often have references to singleton (defualut)DAOs, and the
DAOs might

have references to Hibernate SessionFactorys, which are thread-safe.

PROTOTYPE SCOPE

***************

***************

Prototype-scoped beans are created every time they’re requested via ApplicationContext’s getBean()
method, or each time they’re injected into other beans.
The last three scopes—request, session and global session—are useful only in the context of web
applications.

( have additional steps if you are using frameworks other than spring MVC)

Request-scoped beans are created each time an HTTP request makes its way into a servlet resource that
is injected with one.

(similar to request-scoped variables in servlets)

Session-scoped beans are confined to the scope of standard session-scoped variables.

it’s restricted to one thread at a time, which is tied to the current session of the client making the
requests.

they exist throughout an entire session. created and managed for each individual portlet.

Global session–scoped beans are applicable only in the context of portlet applications.

they exist throughout an entire session, but they’re shared among all the portlets in a complete portlet
web application,

Additional steps

****************

****************

****************

1) register a Request-

ContextListener in the servlet deployment descriptor (web.xml):


<web-app>

...

<listener>

<listener-class>

org.springframework.web.context.request.RequestContextListener

</listener-class>

</listener>

...

</web-app>

These listeners and filters enable the required integration between Spring and whatever servlet
container you’re using.

Spring can intercept requests and decorate them with this scoping functionality.

beans with request, session and global session scope should be intialized from Spring context that are
aware of web.

(XmlWebApplicationContext)

1.4.3 P namespace ( bean namespace is define in xsd. p namespace dont have XSD. It is implemented in
spring)

*****************

*****************

p namespace extends bean namespace. It uses some XML syntax for application-context.xml
configuration to be consise.

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<bean id="accountService" class="com.springinpractice.ch01.service.AccountService" p:accountDao-


ref="accountDao"/>

compare with (Declare properties as bean element attributes)

<bean id="accountService" class="com.springinpractice.ch01.service.AccountService">

<property name="accountDao" ref="accountDao"/>

</bean>

EG2:

<bean id="dataSource"

class="org.apache.commons.dbcp.BasicDataSource"

destroy-method="close"

p:driverClassName="${dataSource.driverClassName}"

p:url="${dataSource.url}"

p:username="${dataSource.username}"

p:password="${dataSource.password}"

/>

1.4.4) c namespace ( from spring 3.1 )

******************

******************
intended to improve constructor injection. also supports -ref like p namespace.

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:c="http://www.springframework.org/schema/c"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

<bean id="joshAsPerson" class="foo.Person">

<constructor-arg value="Joshua"/>

<constructor-arg value="White"/>

</bean>

<bean id="joshAsPerson" class="foo.Person"

c:firstName="Joshua"

c:lastName="White"/>

<bean id="willieAsPerson" class="foo.Person"

c:_0="Willie"

c:_1="Wheeler"/>

1.5 AUTOWIRING and Component Scanning

*************************************

1.5.1 @AutoWired

****************

****************

import org.springframework.beans.factory.annotation.Autowired;
... other imports omitted ...

public class AccountService {

@Autowired

private AccountDao accountDao;

...

The @Autowired annotation can be applied to constructors or fields and allows you to wire relationships

by type, without having to explicitly set them up in the XML configuration.

and also by avoiding the setters.

When a field is @Autowired, Spring looks through the container for beans with a matching type to
inject.

can be used for constructor DI configuration and Array intialization.

Useless sample that violates singleton DAO, but explains autowired

@Autowired

private AccountDao[] accountDaos;

step 1) You need to use annotation

step2 ) configure the application-context.xml - declare the annotation-config element and enable it
(<context:annotation-config/>)

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<context:annotation-config/>

Now it still allows place-holderconfigurer ( {} parameterization ) and removes constructor properties,


like the one

<bean id="accountDao" class="com.springinpractice.ch01.dao.jdbc.JdbcAccountDao"/>

<bean id="accountService"class="com.springinpractice.ch01.service.AccountService"

p:accountDao-ref="accountDao"/>

NOTE: If you want to use some mimatch named class to be wired, use qualifier.

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Qualifier;

public class AccountService {

@Autowired

@Qualifier("hibernateAccountDao")

private AccountDao accountDao;

Now the AccountDao will be autowired to bean id hibernateAccountDao.


1.5.2 Stereotype annotations

****************************

*****************************

import org.springframework.stereotype.Service;

Still we declare the beans in application-context.xml. We can avoid that too like we avoided property
elements.

1) Spring’s stereotype annotations, you can annotate classes and 1) enable component scanning
(<context:component-scan base-package="com.springinpractice.ch01"/>)

Spring will automatically import the beans into the container

@Component, @Repository, @Service, @Controller

@component - annotation flags a bean so the component-scanning mechanism can pick it up

and pull it into the application context. (generic for all beans)

other three are specialized

@Repository - for DAO ( with feautres transferring exceptions they throw into Springs
DataAccessExceptions)

@service - for service components ( with futuristic features)

@Controller - for spring web MVC controller components with compilimentary annotation
@RequestMapping, to map URLs to instance methods of a class.

1.5.3 Component Scanning

************************

************************

To enable component scanning, update the application-context.xml


<context:component-scan base-package="com.springinpractice.ch01"/>

provide the base package from where the bean/components has to scanned recurssively.

If you have many different packages repeat

<context:component-scan base-package="org.springinpractice.ch01"/>

NOTE: Good news, if you use <context:component-scan> no need to use <context:annotation-config/>


to enable auto wiring. By default it will also be enabled.

Bad news, if you use third party classes from jars, and cant add annotations you have to declare
them in application-context.xml.

So naming of the beans created by component scanning has the naming convention: (their
uncapitalized, nonqualified classnames)

springinpractice.ch01.dao.jdbc.JdbcAccountDao resolves to jdbcAccountDao

you can implement Spring’s BeanNameGenerator interface to customize the naming strategy.

1.5.4 XML vs annotation configuration

*************************************

*************************************

XML config:

Spring supports few classes onl for xml config.

Keeps pojos clean.

multiple xml for DAO, service (each architectural slices) can be helpful.

Annotations:

Spring steering committe inclined to annotations.

seeing the java file that contains the classes ( domain objects or service) you will know the entire info of
these classes with annotations.

Potrebbero piacerti anche