41) What is SQLProvider ?
SQLProvider:
Has one method – getSql()
Typically implemented by PreparedStatementCreator implementers
Useful for debugging.
42) What is RowCallbackHandler ?
The RowCallbackHandler interface extracts values from each row of a ResultSet.
Has one method – processRow(ResultSet)
Called for each row in ResultSet.
Typically stateful.
43) What are the differences between EJB and Spring ? Spring and EJB feature comparison.
44) What is aspect oriented programming (AOP)? Do you have any experience with AOP?
Aspect-Oriented Programming (AOP) complements OOP (Object Oriented Programming) by allowing the
developer to dynamically modify the static OO model to create a system that can grow to meet new requirements.
AOP allows you to dynamically modify your static model consisting mainly of business logic to include the code required to fulfill the secondary requirements or in AOP terminology called cross-cutting concerns (i.e. secondary requirements) like auditing, logging, security, exception handling etc without having to modify the original static model (in fact, we don't even need to have the original code). Better still, we can often keep this additional code in a single location rather than having to scatter it across the existing model, as we would have to if we were using OOP on its own.
For example; A typical Web application will require a servlet to bind the HTTP request to an object and then pass it to the business handler object to be processed and finally return the response back to the user. So only a minimum amount of code is initially required. But once you start adding all the other additional secondary requirements or cross-cutting concerns like logging, auditing, security, exception-handling, transaction demarcation, etc the code will inflate to 2-4 times its original size. This is where AOP can assist by separately modularizing these cross-cutting concerns and integrating theses concerns at runtime or compile time through. aspect weaving. AOP allows rapid development of an evolutionary prototype using OOP by focusing only on the business logic by omitting concerns such as security, auditing, logging etc. Once the prototype is accepted, additional concerns like security, logging, auditing etc can be weaved into the prototype code to transfer it into a production standard application.
AOP nomenclature is different from OOP and can be described as shown below:
Join points: represents the point at which a cross-cutting concern like logging, auditing etc intersects with a main concern like the core business logic. Join points are locations in programs’ execution path like method & constructor call, method & constructor execution, field access, class & object initialization, exception handling execution etc.
pointcut: is a language construct that identifies specific join points within the program. A pointcut defines a collection of join points and also provides a context for the join point.
Advice: is an implementation of a cross-cutting concern which is a piece of code that is executed upon reaching a pointcut within a program.
Aspect: encapsulates join points, pointcuts and advice into a reusable module for the cross-cutting concerns which is equivalent to Java classes for the core concerns in OOP. Classes and aspects are independent of one another. Classes are unaware of the presence of aspects, which is an important AOP concept. Only pointcut declaration binds classes and aspects.
Weaving is the process for interleaving separate cross-cutting concerns such as logging into core concerns such as business logic code to complete the system. AOP weaving composes different implementations of aspects into a cohesive system based on weaving rules. The weaving process (aka injection of aspects into Java classes) can happen at:
Compile-time: Weaving occurs during compilation process.
Load-time: Weaving occurs at the byte-code level at class loading time.
Runtime: Similar to load-time where weaving occurs at byte-code level during runtime as join points are
reached in the executing application.
So which approach to use? Load-time and runtime weaving have the advantages of being highly dynamic and
enabling changes on the fly without having to rebuild and redeploy. But Load-time and runtime weaving adversely affect system performance. Compile time weaving offers better performance but requires rebuilding and redeployment to effect changes.
Two of the most interesting modules of the Spring framework are AOP (Aspect Oriented Programming) and Inversion Of Control (IoC) container (aka Dependency Injection). Let us look at a simple AOP example.
STEP 1: Define the interface and the implementation classes. Spring promotes the code to interface design
concept.
public interface Hello {
public void hello();
}
public class HelloImpl implements Hello{
public void hello() {
System.out.println("Printing hello. ");
}
}
STEP 2: Configure the Spring runtime via the SpringConfig.xml file. Beans can be configured and subsequently
injected into the calling Test class.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/springbeans.
dtd">
<beans>
<!-- bean configuration which enables dependency injection -->
<bean id="helloBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<bean class="HelloImpl" singleton="false" />
</property>
</bean>
</beans>
STEP 3: Write your Test class. The “SpringConfig.xml” configuration file should be in the classpath.
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("SpringConfig.xml");
Hello h = (Hello)ctx.getBean("helloBean");
h.hello();
}
}
If you run the Test class, you should get an output of :
Printing hello.
Now, if you want to trace your methods like hello() before and after in your Hello class, then you can make use of the Spring AOP.
STEP 4: Firstly you need to define the classes for the before and after advice for the method tracing as follows:
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class TracingBeforeAdvice implements MethodBeforeAdvice {
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("Just before method call...");
}
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class TracingAfterAdvice implements AfterReturningAdvice {
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3)
throws Throwable {
System.out.println("Just after returning from the method call...");
}
}
STEP 5: In order to attach the advice to the appropriate joint points, you must make a few amendments to the
SpringConfig.xml file as shown below in bold:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/springbeans.
dtd">
<beans>
<!-- bean configuration which enables dependency injection -->
<bean id="helloBean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<bean class="HelloImpl" singleton="false" />
</property>
<property name="interceptorNames">
<list>
<value>traceBeforeAdvisor</value>
<value>traceAfterAdvisor</value>
</list>
</property>
</bean>
<!-- Advice classes -->
<bean id="tracingBeforeAdvice" class="TracingBeforeAdvice" />
<bean id="tracingAfterAdvice" class="TracingAfterAdvice" />
<!-- Advisor: way to associate advice beans with pointcuts -->
<!-- pointcut definition for before method call advice -->
<bean id="traceBeforeAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="tracingBeforeAdvice" />
</property>
<property name="pattern">
<!-- apply the advice to Hello class methods -->
<value>Hello.*</value>
</property>
</bean>
<!-- Advisor: way to associate advice beans with pointcuts -->
<!-- pointcut definition for after returning from the method advice -->
<bean id="traceAfterAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="tracingAfterAdvice" />
</property>
<!-- apply the advice to Hello class methods -->
<property name="pattern">
<value>Hello.*</value>
</property>
</bean>
</beans>
If you run the Test class again, you should get an output with AOP in action:
Just before method call...
Printing hello.
Just after returning from the method call...
45) What are the differences between OOP and AOP?
OOP:
OOP looks at an application as a set of collaborating objects. OOP code scatters system level code like logging, security etc with the business logic code.
OOP nomenclature has classes, objects, interfaces etc.
Provides benefits such as code reuse, flexibility, improved maintainability, modular architecture, reduced development time etc with the help of polymorphism, inheritance and encapsulation.
AOP:
AOP looks at the complex software system as combined implementation of multiple concerns like business logic, data persistence, logging, security, multithread safety, error handling, and so on. Separates business logic code from the system level code. In fact one concern remains unaware of other concerns.
AOP nomenclature has join points, point cuts, advice, and aspects.
AOP implementation coexists with the OOP by choosing OOP as the base language. For example: AspectJ uses Java as the base language.
AOP provides benefits provided by OOP plus some additional benefits which are discussed in the next question.
46) What are the benefits of AOP?
OOP can cause the system level code like logging, transaction management, security etc to scatter throughout the business logic. AOP helps overcome this problem by centralizing these cross-cutting concerns.
AOP addresses each aspect separately in a modular fashion with minimal coupling and duplication of code.
This modular approach also promotes code reuse by using a business logic concern with a separate logger
aspect.
It is also easier to add newer functionalities by adding new aspects and weaving rules and subsequently
regenerating the final code. This ability to add newer functionality as separate aspects enable application
designers to delay or defer some design decisions without the dilemma of over designing the application.
Promotes rapid development of evolutionary prototypes using OOP by focusing only on the business logic by omitting cross-cutting concerns such as security, auditing, logging etc. Once the prototype is accepted,
additional concerns like security, logging, auditing etc can be weaved into the prototype code to transfer it into a production standard application.
Developers can concentrate on one aspect at a time rather than having to think simultaneously about business logic, security, logging, performance, multithread safety etc. Different aspects can be developed by different developers based on their key strengths. For example: A security aspect can be developed by a security expert or a senior developer who understands security.
47) What is inversion of control (IoC) (also known more specifically as dependency injection)?
Inversion of control or dependency injection (which is a specific type of IoC) is a term used to resolve object
dependencies by injecting an instantiated object to satisfy dependency as opposed to explicitly requesting an object. So objects will not be explicitly requested but objects are provided as needed with the help of an Inversion Of Controller container (e.g. Spring, Hivemind etc). This is analogous to the Hollywood principal where the servicing objects say to the requesting client code (i.e. the caller) “don’t call us, we’ll call you”. Hence it is called inversion of control.
Most of you all are familiar with the software development context where client code (requesting code)
collaborates with other dependent objects (or servicing objects) by knowing which objects to talk to, where to locate them and how to talk with them. This is achieved by embedding the code required for locating and
instantiating the requested components within the client code. The above approach will tightly couple the
dependent components with the client code.
Caller code:
class CarBO {
public void getCars(String color) {
//if you need to use a different implementation class say FastCarDAOImpl then need to
//make a change to the caller here (i.e. CarDAO dao = new FastCarDAOImpl()). so the
//caller is tightly coupled. If this line is called by 10 different callers then you
//need to make changes in 10 places.
CarDAO dao = new CarDAOImpl();
List listCars = dao.findCarsByColor(color);
}
}
Being called code:
interface CarDAO (){
public abstract List findCarsByColor(color);
}
interface CarDAOImpl extends CarDAO (){
public List findCarsByColor(color) {
//data access logic goes here
}
}
This tight coupling can be resolved by applying the factory design pattern and program to interfaces not to
implementations driven development.
Simplified factory class implemented with a singleton design pattern:
class CarDAOFactory {
private static final CarDAOFactory onlyInstance = new CarDAOFactory();
private CarDAOFactory(){}//private so that cannot be instantiated from outside the class
public CarDAOFactory getInstance(){
return onlyInstance;
}
public CarDAO getDAO(){
//if the implementation changes to FastCarDAOImpl then change here only instead of 10
//different places.
return new CarDAOImpl();
}
}
Now the caller code should be changed to:
class CarBO {
public void getCars(String color) {
//if you need to use a different implementation class say FastCarDAOImpl then need to
//make one change only to the factory class CarDAOFactory to return a different
//implementation (i.e. FastCarDAOImpl) rather than having to change all the callers.
CarDAO dao = CarDAOFactory.getInstance().getDAO();
List listCars = dao.findCarsByColor(color);
}
}
But the factory design pattern is still an intrusive mechanism because servicing objects need to be requested
explicitly. Also if you work with large software systems, as the system grows the number of factory classes can
become quite large. All the factory classes are simple singleton classes that make use of static methods and field
variables, and therefore cannot make use of inheritance. This results in same basic code structure repeated in all
the factory classes.
Let us look at how dependency injection comes to our rescue. It takes the approach that clients declare their
dependency on servicing objects through a configuration file (like spring-config.xml) and some external piece of
supplying the relevant references when needed to the client code whereby acting as the factory objects. This
external piece of code is often referred to as IoC (specifically known as dependency injection) container or
framework.
SpringConfig.xml
<beans>
<bean id="car" class="CarBO" singleton="false" >
<constructor-arg>
<ref bean="carDao" />
</constructor-arg>
</bean>
<bean id="carDao” class="CarDAOImpl" singleton="false" />
</beans>
Now your CarBO code changes to:
class CarBO {
private CarDAO dao = null;
public CarBO(CarDAO dao) {
this.dao = dao;
}
public void getCars(String color) {
//if you need to use a different implementation class say FastCarDAOImpl then need to
//make one change only to the SpringConfig.xml file to use a different implementation
//class(i.e. class=”FastCarDAOImpl”) rather than having to change all the callers.
List listCars = dao.findCarsByColor(color);
}
}
Your calling code would be (e.g. from a Web client or EJB client ):
ApplicationContext ctx = new FileSystemXmlApplicationContext("SpringConfig.xml");
//lookup “car” in your caller where “carDao” is dependency injected using the constructor.
CarBO bo = (CarBO)ctx.getBean("car"); //Spring creates an instance of the CarBO object with
//an instance of CarDAO object as the constructor arg.
String color = red;
bo.getCars(color)
You can use IoC containers like Spring framework to inject your business objects and DAOs into your calling
classes. Dependencies can be wired by either using annotations or using XML as shown above. Tapestry 4.0
makes use of the Hivemind IoC container for injecting application state objects, pages etc.
IoC or dependency injection containers generally control creation of objects (by calling “new”) and resolve
dependencies between objects it manages. Spring framework, Pico containers, Hivemind etc are IoC containers to name a few. IoC containers support eager instantiation, which is quite useful if you want self-starting services that “come up” on their own when the server starts. They also support lazy loading, which is useful when you have many services which may only be sparsely used.
48) What are the benefits of IoC (aka Dependency Injection)?
Minimizes the amount of code in your application. With IoC containers you do not care about how services are created and how you get references to the ones you need. You can also easily add additional services by
adding a new constructor or a setter method with little or no extra configuration.
Makes your application more testable by not requiring any singletons or JNDI lookup mechanisms in your unit test cases. IoC containers make unit testing and switching implementations very easy by manually allowing you to inject your own objects into the object under test.
Loose coupling is promoted with minimal effort and least intrusive mechanism. The factory design pattern is
more intrusive because components or services need to be requested explicitly whereas in IoC the
dependency is injected into the requesting code. Also some containers promote the design to interfaces not to implementations design concept by encouraging managed objects to implement a well-defined service
interface of your own.
IoC containers support eager instantiation and lazy loading of services. Containers also provide support for
instantiation of managed objects, cyclical dependencies, life cycle management, and dependency resolution
between managed objects etc.