spring_di

53
1

Upload: pendekanti-surendra-kumar

Post on 21-Mar-2016

213 views

Category:

Documents


0 download

DESCRIPTION

Spring_DI - JEE

TRANSCRIPT

1

2

3

4

The MyLogic class does not know about the MyBusinessService internal’s, but instead depends on the factory. To test the MyLogic class doTask() method we do not need the actual MyBusinessServiceImpl, instead the Factory class can be configured to provide mock implementation(MyBusinessServiceMock). MyServiceFactory class should support modifications to support testing.

The factory pattern solves many of the problems which we encounter when construction by-hand.

Problem: The factory pattern must accompany every service is troubling. Not only this, a factory must accompany every variation of every service. This is a sizable amount of distracting clutter and adds a a lot of peripheral code to be tested and maintained .

Code Snippet:

public class MyLogic {

private MyBusinessService service;

public void doTask() {

// Use the Factory class to retreive the business object

MyBusinessService businessService = MyServiceFactory.getBusinessService();

// perform the logic

businessService.invokeSomeMethod();

}

}

5

The service locator pattern is a design pattern used in software development to encapsulate the processes involved in obtaining a service with a strong abstraction layer.

This code is difficult to unit test, because how we retrieve the dependency is coded inside the class (MyLogic class) we need to unit test.

Also JNDI needs application server and hence without deploying on application server it is difficult to unit test.

Code Snippet:

public class MyLogic {

private MyBusinessService service;

public void doTask() {

// Use the InitialContext to retreive the business object

InitialContext ctx = new InitialContext();

MyBusinessService businessService = (MyBusinessService) ctx.lookup(“BSERV”);

// perform the logic

businessService.invokeSomeMethod();

}

}

6

7

8

Inversion of Control container assembles the Dependent and the Provider, injects the Provider into the Dependent and gives you the possibility of selecting which Provider implementation to inject into each Dependent.

Now the IoC Container can inject either MyBusinessServiceImpl or MyBusinessserviceMock into MyLogic class without the need to modify even a single line of code in the application.

List of few popular Inversion Of Control Containers:

1) PicoContainer :http://picocontainer.org/injection.html

2) Avalon Framework (Retired) : http://excalibur.apache.org/framework/

3) Guice Framework: http://code.google.com/p/google-guice/

4) Spring Framework:http://www.springsource.org/

9

10

Lightweight Container:

•Light weight container is one that can manage application code, but imposes no special dependencies on that code.

•Light weight container should have a light footprint and can run in different environments.

•A lightweight container should be pure Java and not JEE only.

•Light weight container should be quick to start.

•Light weight container doesn’t require any special deployment steps to deploy objects within it.

•Light weight container should have the ability to add managed objects easily with low deployment effort and performance overhead.

11

The Spring Framework consists of features organized into about 20 modules. These modules are grouped into Core Container, Data Access/Integration, Web, AOP (Aspect Oriented Programming), Instrumentation, and Test.

Core Container

The Core and Beans modules provide the fundamental parts of the framework, including the IoC and Dependency Injection features.

The Context module inherits its features from the Beans module and adds support for internationalization (using, for example, resource bundles), event-propagation, resource-loading, and the transparent creation of contexts by, for example, a servlet container.

The Context module also supports Java EE features such as EJB, JMX ,and basic remoting.

The Expression Language module provides a powerful expression language for querying and manipulating an object graph at runtime.

Data Access/Integration

The JDBC module provides a JDBC-abstraction layer that removes the need to do tedious JDBC coding and parsing of database-vendor specific error codes.

The ORM module provides integration layers for popular object-relational mapping APIs,.

The OXM module provides an abstraction layer that supports Object/XML mapping implementations for JAXB, Castor, XMLBeans, JiBX and XStream.

The Java Messaging Service (JMS) module contains features for producing and consuming messages.

The Transaction module supports programmatic and declarative transaction management for classes that implement special interfaces and for all your POJOs .

Web

Spring's Web module provides basic web-oriented integration features such as multipart file-upload functionality and the initialization of the IoC container using servletlisteners and a web-oriented application context. It also contains the web-related parts of Spring's remoting support.

The Web-Servlet module contains Spring's model-view-controller (MVC) implementation for web applications.

The Web-Struts module contains the support classes for integrating a classic Struts web tier within a Spring application. Note that this support is now deprecated as of Spring 3.0. Consider migrating your application to Struts 2.0 and its Spring integration or to a Spring MVC solution.

The Web-Portlet module provides the MVC implementation to be used in a portlet environment and mirrors the functionality of Web-Servlet module.

AOP and Instrumentation

Spring's AOP module provides aspect-oriented programming implementation

The Instrumentation module provides class instrumentation support and classloader implementations to be used in certain application servers.

Test

The Test module supports the testing of Spring components with JUnit or TestNG..

12

13

Interface BeanFactory: The root interface for accessing a Spring bean container. This is the basic client view of a bean container.

Interface MessageSource: for resolving messages, with support for the parameterization and internationalization of such messages

Interface ApplicationContext: Central interface to provide configuration for an application

Note: ApplicationContext also extends HierarchicalBeanFactory, ResourceLoader, ResourcePatternResolver

Methods:

boolean containsBean(String name) Does this bean factory contain a bean with the given name

T getBean(Class<T> requiredType) Return the bean instance that uniquely matches the given object type, if any.

Object getBean(String name) Return an instance of the specified bean.

T getBean(String name, Class<T> requiredType) Return an instance of the specified bean.

boolean isTypeMatch(String name, Class targetType) Check whether the bean with the given name matches the specified type.

String[] getBeanDefinitionNames() Return the names of all beans defined in this factory.

int getBeanDefinitionCount() Return the number of beans defined in the factory.

14

The org.springframework.beans.factory.xml.XmlBeanFactory is one of the commonly used implementation class for BeanFactory.

The ClassPathXmlApplicationContext, FileSystemXmlApplicationContext and XmlWebApplicationContext are some of the commonly used implementation classes of ApplicationContext interface.

BeanFactory is preferred over ApplicationContext only in scenario’s where resources constraints exist(example mobile apps).

15

16

Note: Configuration file name can be anything.

When an Spring container (application context) is loaded as illustrated below container instantiates all the beans configured in the xml file until it is configured for lazy-initialization.

ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

Equivalent java code for:

<bean id="rahulAccount" class="com.mindtree.entity.Account">

<constructor-arg index="0" value="SB500" />

<constructor-arg index="1" value="Rahul B Prakash" />

<constructor-arg index="2" value="8590.50" />

</bean>

is

com.mindtree.entity.Account rahulAccount = new com.mindtree.entity.Account(“SB500”, “Rahul B Prakash”, 8590.50);

--------------------------------------------------

Prefer type over index for constructor argument matching : Spring allows you to use a zero-based index to solve the ambiguity problem when a constructor has more than one arguments of the same type, or value tags are used.

17

18

19

20

Equivalent java code for:

<bean id="deepaAccount" class="com.mindtree.entity.Account">

<property name="accountNumber" value="SB922" />

<property name="accountOwner" value="Deepa" />

<property name="balance" value="3455.55" />

</bean>

is

com.mindtree.entity.Account deepalAccount = new com.mindtree.entity.Account();

deepaAccount.setAccountNumber(“SB922”);

deepaAccount.setAccountOwner(“Deepa”);

Deepaccount.setBalance(3455.55);

21

22

23

(1) Configure com.mindtree.dao.AccountInMemoryImpl bean an implementation of com.mindtree.dao.AccountDao to be instantiated and managed by the Spring container.

(2) rahulAccount an instance of com.mindtree.entity.Account is instantiated using constructor based dependency injection

(3) deepAccount an instance of com.mindtree.entity.Account is instantiated using setter based dependency injection

(4) Load Spring Container (ApplicationContext) and instantiate/manage all beans configured in beans.xml, which is present in the classpath.

(5) Get the bean “rahulAccount” which is ready to use and managed by the spring container.

(6) Get the bean “accountDao”.

T getBean(String name, Class<T> requiredType) : Return an instance of the specified bean of requiredType.

Refer: Dependency_Injection_1.zip for complete working application used in this presentation.

24

Sequence diagram for the following configuration in “beans.xml”.

<bean id="rahulAccount" class="com.mindtree.entity.Account">

<constructor-arg index="0" value="SB500" />

<constructor-arg index="1" value="Rahul B Prakash" />

<constructor-arg index="2" value="8590.50" />

</bean>

<!-- Set properties using setter injection -->

<bean id="deepaAccount" class="com.mindtree.entity.Account">

<property name="accountNumber" value="SB922" />

<property name="accountOwner" value="Deepa" />

<property name="balance" value="3455.55" />

</bean>

25

26

27

28

In the “constructor-arg”we can’t use “value” to for the constructor argument because a AccountDaoInMemoryImpl is not a simple type.

Instead, the “ref” attribute is used to indicate that the value passed to the constructor should be a reference to the bean whose ID is “accountDao”.

Although the Spring container does much more than just construct beans, you may imagine that when Spring encounters the “accountDao” and “transferService” <bean>s, it performs some logic that is essentially the same as the following lines of Java:

AccountDaoInMemoryImpl accountDao = new AccountDaoInMemoryImpl();

TransferServiceImpl transferService = new TransferServiceImpl(accountDao);

Instead of Constructor-based dependency injection if setter based injection is done to TransferService, changes will be:

Configuration:

<bean id="transferService" class="com.mindtree.service.TransferServiceImpl">

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

</bean>

Java Code:

public class TransferServiceImpl implements TransferService {

private AccountDao accountDao;

/**

* @param accountDao the accountDao to set

*/

public void setAccountDao(AccountDao accountDao) {

this.accountDao = accountDao;

}

@Override

public void transferFunds(String fromAccount, String destAccount,

double amount) {

Account srcAcct = accountDao.getAccount(fromAccount);

Account destAcct = accountDao.getAccount(destAccount);

srcAcct.debit(amount);

destAcct.credit(amount);

accountDao.updateAccount(srcAcct);

accountDao.updateAccount(destAcct);

}}

Refer: Dependency_injection_2.zip for complete code

29

30

Arguments to the static factory method getAccountDao(String type) are supplied via <constructor-arg/> elements, exactly

the same as if a constructor had actually been used.

The type of the class being returned (AccountDao) by the factory method does not have to be of the same type as the class (AccountDaoFactory) that contains the static factory method.

In the line: AccountDao accountDao = context.getBean(“accountDaoFactory”, AccountDao.class);

The argument to the getBean is an ID of AccountDaoFactory, but the returned bean is of type returned from Factory-method.

Note:

An instance (non-static) factory method would be used in an essentially

identical fashion (aside from the use of the factory-bean attribute instead of the class attribute),

31

32

Answers:

1) <bean id=“prd" class="com.mindtree.entity.Product">

<constructor-arg type=“int” value="00" />

<constructor-arg type=“java.lang.String” value=“Dell Laptop" />

<constructor-arg type=“double” value=“48590.50" />

</bean>

2) <bean id=“preeti" class="com.mindtree.entity.Customer">

<property name=“firstName" value=“Preeti" />

<property name=“email" value=“[email protected]” />

<property name=“password" value=“Secret123" />

</bean>

33

Answers:

3) <bean id="connection" class="java.sql.DriverManager" factory-method="getConnection">

<constructor-arg index="0" value="jdbc:mysql://localhost:3306/HibernateDB" />

<constructor-arg index="1" value="root" />

<constructor-arg index="2" value="root" />

</bean>

34

Spring can autowire dependencies through introspection of the bean classes so that you do not have to explicitly specify the bean properties or constructor arguments.

35

Since the argument to TransferServiceImpl constructor is of type AccountDao, the Spring container injects instance of AccountDao to TransferServiceImpl.

It eliminates explict mention of construct-arg element as shown below:

<bean id="transferService" class="com.mindtree.service.TransferServiceImpl">

<constructor-arg ref="accountDao" />

</bean>

36

byType: Spring container attempts to find a single bean in the container whose type matches the type of the property being wired.

If no matching bean is found, the property will not be wired.

If more than one bean matches, an org.springframework.beans.factory.UnsatisfiedDependencyException will be thrown.

Similarly:

byName: Spring container attempts to find a bean in the container whose name (or ID) is the same as the name of the property being wired.

If a matching bean is not found, the property will remain unwired.

autodetect: Spring container attempts to autowire by constructor first and then using byType.

Ambiguity is handled the same way as with constructor and byType wiring.

Mixing auto with explicit wiring: Just because you choose to autowire a bean, that doesn’t mean you can’t explicitly

wire some properties. You can still use the <property> element on any property as if you hadn’t set autowire.

37

38

39

40

Annotation injection is performed before XML injection, thus the latter configuration will override the former for properties wired through both approaches.

41

Similarly the following are also valid ways to use @Autowired annotation in TransferServiceImpl class

1) @Autowired applied to setter method:

/**

* @param accountDao the accountDao to set

*/

@Autowired

public void setAccountDao(AccountDao accountDao) {

this.accountDao = accountDao;

}

2) @Autowired applied to field :

@Autowired

private AccountDao accountDao;

3) @Autowired applied to arbitrary method:

@Autowired

public void prepare(AccountDao accountDao ) {42

43

44

45

46

Answer:

1) Dependency injection using constructor

<bean id=“bobj” class=“B” />

<bean id=“a" class=“a">

<constructor-arg ref=“bobj" />

</bean>

2) Dependency injection using setter

<bean id=“bobj” class=“B” />

<bean id=“a" class=“a">

<property name=“b” ref=“bobj" />

</bean>

3) Dependency injection using autowire=“byType” , autowire=“byName”, autoWire=“constructor”

<bean id=“bobj” class=“B” />

<bean id=“a" class=“a“ autowire="byType" />

4) Dependency injection using @Autowired annotation

class A {

@Autowired

private B b;

….

}

47

Answer: Except (b) and (f) all other are valid ways to inject “second” reference into First entity.

48

49

50

51

52

53