Spring Framework

Spring Core

https://medium.com/omarelgabrys-blog/spring-a-head-start-beans-configuration-part-2-4a8c239b070a#:~:text=%F0%9F%94%A6%20Java%20Annotations%20Vs%20XML,override%20that%20of%20the%20annotations.

Spring has many parts. Core is about dependency injection /version where we have to decouple the classes.

Spring has containers just like a Tomcat has called a container. It manages the lifecycle of an object mentioned in XML similar to Tomcat.

This works based on Factory Pattern – A factory class can instantiate all the objects.

So if you ask for an Object to Spring Bean Factory – it will give you that particular object.

<xml >

<DocType ..
<bean id=” class=”” />

  1. XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource(“Beans.xml”));

2. BeanFactory factory = new ClassPathXmlApplicationContext(“spring.xml”); 
Triangle triangle = (Triangle) factory.getBean(“triangle”);

Now if the triangle class was very complicated which required multiple other classes the bean def would change accordingly. The advantage is that you can get the Triangle class with just one statement instead of defining several of its dependencies every time the class is instantiated at multiple places.


You can also use ApplicationContext instead of BeanFactory
The ApplicationContext interface is built on top of the BeanFactory interface. It adds some extra functionality such as simple integration with Spring’s AOP, message resource handling (for I18N), event propagation, application layer specific context (e.g. WebApplicationContext) for web application, annotation based dependency .

BeanFactory uses lazy initialization but ApplicationContext uses eager initialization. 

However, to lazy load a bean via ApplicationContext once can use lazy-init=”true” in bean definition.

Note : only singletons have the concept of lazy and eager loading, prototype are always made on request basis so they are loaded on request (lazily only).

For Java class based configuration

ApplicationContext ctx = new AnnotationConfigApplicationContext(HelloWorldConfig.class);
 

HelloWorldConfig class willl @Configuration over it

@Import(HelloWorldConfig2.class)

HelloWorldConfig2 configuration class is imported into HelloWorldConfig 

The above two methods are for setter injection. <property name=”” value=””>

Constructor based injection

We can inject using constructor for the class.
<bean..>

 <constructor-arg value”” type=”” index=””>

</bean>

Type and index r optional

Type defines type of class of argument – java.lang.String – to be used to explicitly say that this argument is of type String
Index – position of argument – to be used if multiple String args etc are there

Refer objects in a class/ Injection Objects

If a class has member variables as objects – they will be defined in spring.xml and can be used as

<bean …>

<property name=”” ref=”<ref bean id here>” /> (instead of value we use ref to refer another bean)

</bean>

Idref vs ref

<bean class=”A” id=”a” /> 

<bean class=”B”/>
<constructor-arg>
<ref bean=”a”/>
<idref bean=”a”/>
</constructor-arg>
</bean>

public B(A a, String string) {
string.equals(“a”); //true
}

So with ref you can reference an object and with idref you just reference the name of the bean

For idref one could have used direct string property

<constructor-arg type = “java.lang.String” value = “Zara”/>

But if you use idref it  ensures at deployment time that bean with that name exists otherwise it will throw error. 

InnerBean

<bean …>

<property name=”” >

<bean class = “” ></bean>

</property>

</bean>

Alias

<alias name “<bean id>”  alias””/>

Initializing collection Objects

For string values

<property name = “addressList”>
        <list> -> could also be <set> / <map>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>USA</value>
        </list>
      </property>

For map

<map>
            <entry key = “1” value = “INDIA”/>

</map>

For objects

<bean>

<property name=”” >

<list>

<ref  bean =””>

<ref  bean =””>

</list>

</property>

</bean>

Injecting null values

<property name = “email”><null/></property>

Types of bean scope

  1. Singleton – one object of a bean per spring container
  2. Prototype – multiple objects of bean per spring container – default
  3. Global – one object per HTTP application. [MVC]
  4. Session – one object per HTTP session. [MVC]
  5. Request – one object per HTTP Request[MVC]

<bean id=”” type =”” scope=””>

Interfaces which class can implement to get information

ApplicationContextAware

MYclass implements ApplicationContextAware

@overrider

Void setContext… (AC content ) {

this.context = context;

}

This way you can fetch the context in the class, similar interfaces exist like BeanNameAware etc.

Note that in newer versions it may be better to use annotations, rather than implementing spring-specific interfaces. Now you can simply use:

@Inject // or @Autowired
private ApplicationContext ctx;

Bean Definition Inheritance

Just like inheritance there is parent child relationship in bean definitions too.

Two beans can be defined by that relationship. The child can override the properties of the parent if it defines the same properties again.

<bean id =type= abstract= parent=

One could define a bean abstract or child of some bean using parent.

Bean Definition Template

You can create a Bean definition template, which can be used by other child bean definitions without putting much effort. 

<bean id = “beanTeamplate” abstract = “true”>

Lifecycle Methods

Called before initialization and destruction

Can be called in Two ways for each bean

  1. Implementing Initializingbean, DisposableBean / BeanPostProcessor
  2. Using xml to define init-method, destroy-method in bean definition

<bean id = “helloWorld” class = “com.gaurav.HelloWorld”
      init-method = “init” destroy-method = “destroy”>

On a global level – <beans > every bean will be searched for the default-init-method, default-destroy-method

In any of the methods above each bean will have a seperate method for initialization and destruction.

Common method for Initialization for all beans can be given in the following manner.

  1. Implement BeanPostProcessor
  2. register it in spring.xml

The same method will execute for all beans

Property Substitution

If you want to assign a value of a bean through properties file then it can be done by

  1. Register PropertyPlacementHolderConfig in spring.xml
  2. Inside it a property will have value as the location/name of the properties file

      3.

<bean class=”org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”

 >

<property name=”” value = “${property1.propertyA}”>

// or give an entire properties file

<property name=”location”>
<value>database.properties</value>
</property>

The property file can be Used like this
<property name=”driverClassName” value=”${jdbc.driverClassName}” />

To use the value in a bean file

@Value( “${jdbc.url}” ) private String jdbcUrl;

@Required – if a function need to be called at the time of initiation then it has to be annotated accordingly so that if it setter the attribute which will be accessed should not give NullPointerException


@Required

Void setValue( String a)

The error will be thrown at applications start up.

You need to add a postprocessor in spring.xml to use annotation.

Also in case  of optional dependency injection this can be used.

public class FooService {

    @Autowired(required = false)
    private FooDAO dataAccessor;
   
}

Else it can throw nosuchbeanfoundexception

Autowiring
If you want bean injected automatically. Not constructor injection.

Types

Name – ids of all beans should be same as member variables

Type – if there r member variables of different types. No two member variables should be of same type.

@Autowired -. It will search for the type of this class in spring container , if it finds multiple entries then it searches for name match. If it doesn’t find then it fails.

Solving UnsatisfiedDependencyException with Spring autowiring

To overcome this problem there are two options

  • primary candidate – Identify a primary candidate for auto wiring bean and set that as primary=”true”
  • <bean id=”payment” class=”org.netjs.springexp.prog.CashPayment” primary=”true”/>
  • Exclude a bean from autowiring – You can exclude a bean from being autowired. For that set the autowire-candidate attribute of <bean> tag to false.
  • <bean id=”creditPayment” class=”org.netjs.springexp.prog.CreditPayment” autowire-candidate=”false” />

@Autowired over a constructor

If there are more than one constructor in the class, only one constructor can have @Autowired annotation. This constructor should not be public.

@Autowired with Field

The class field can also be autowired using @Autowired annotation. Any number of fields can be autowired within a class. The fields which are autowired should not be public

@Qualifier(“qualifier”) – this is used with @Autowired to specify which bean to autowire.
The same qualifier needs to given in bean definition in spring.xml

@Autowired
  @Qualifier(“student1”)
  private Student student;

JSR 250 Annotations

@Resource – to inject based on the name same as @Autowired + @Qualifier used over functions.

If you don’t want to use two annotations (the @Autowired and @Qualifier) you can use @Resource to combine these two.

@Inject = @Autowired (@Inject is JSR specification, @Autowired is spring specific)

<bean id=”a” class=”org.sssit.A” autowire=”constructor”></bean>

IF class has multiple constructors then by default the constructor with highest number of parameters is injected.

<bean id=”a” class=”org.sssit.A” autowire=”byName”></bean> 

If the properties of A name is not found – throws Exception

<bean id=”a” class=”org.sssit.A” autowire=”byType”></bean> 

IF multiple beans of same type found again throws Exception

<bean id=”a” class=”org.sssit.A” autowire=”no”></bean>

@PostConstruct @PreDestroy – same as init and destroy methods.

You need to add a post processor in spring.xml to use this annotation.

One simple way to avoid all annotation related post processors is  using

<context:annotation-config/>

@component – marks a class as a bean, it will auto instantiated with no mapping in spring.xml

It will have name same as class with a small letter.

<context:component-scan: base-package=””/> – scans these package to find @component, @Repository, @Controller annotations

Message Source – Resource bundle

Register a bean for the class ResourceBundleMessageSource along with resource bundles as a list

<bean id=”messageSource” class=”org.springframework.context.support.ResourceBundleMessageSource”>
<property name=”basename”>
<value>locale\customer\messages</value>
</property>
</bean>

The MessageSource object can be wired into any class to take this bean.

messageSource.getMessage(<property name>, <args to message>, <default message>, <locale> );

Listeners

You can implement listeners which listen events

Implementing ApplicationListener make a  listener – which listens

A class which has to be publish an event has to implement ApplicationEventPublishAware

This class needs to have a setter for the publisher which the Spring will set from the application context.

This publisher can publish the event.

context:component-scan
Scans for all these annotations

  • @Component
  • @Repository
  • @Service
  • @Controller

One advantage of this element is that it also resolves @Autowired and @Qualifier annotations. Therefore if you declare <context:component-scan>, is not necessary anymore declare <context:annotation-config> too.

Context:annotation-config – scans for Annotations only in already defined beans in XML file.

mvc:annotation-config

used for enabling the Spring MVC components with its default configurations.

  • Support for formatting Number fields with @NumberFormat
  • Support for formatting Date, Calendar, and Joda Time fields with @DateTimeFormat, if Joda Time is on the classpath
  • Support for validating @Controller inputs with @Valid, if a JSR-303 Provider is on the classpath
  • Support for reading and writing XML, if JAXB is on the classpath
  • Support for reading and writing JSON, if Jackson is on the classpath

context:annotation-driven

 it will resolve @Autowired and @Qualifier annotations for the beans which are already created and stored in the spring container.

context:component-scan can also do the same job, but context:component-scan will also scan the packages for registering the beans to application context. context:annotation-config will not search for the beans registration, this will only activate the already registered beans in the context.

Spring AOP

Why AOP? 

In object oriented programming there are many cross cutting concerns which are not specific to an object. These are required globally by the application 

Like logging

Security

Transactions

If they are used in OOP then there are some problems 

  1. Too many relationships with these classes. – Classes are tightly coupled.
  2. Code is required in all classes
  3. Need to change code of every class using these common classes in case there is change.

How AOP Helps?

  1. It is a common unit – provides configurable options where to call these common functions for each class.
  2. There is low coupling
  3. Code need not be changed in every class – just configuration.

Just like Triggers in SQL, Filters in Servlets.

Installation 

Aspecjrtr.jar

Aspectjrtweaver.jar

Cglib.jar – used for generating classes by Spring. Spring modifies the original java source to add the Aspects at appropriate points and then generates a class. This library can add classes to a java program after the compilation phase as JAVA programs are linked during the runtime phase so this works.

Asm.jar – cglib is built over it.

Implementation

  1. A class which defines cross cutting concerns must be labelled as @Aspect
  2. The functions of this class are called Advice. These can be called before/after execution of any method in the spring container.
  3. @Before execution ( public String getName() ) annotation over the Advice

@Before execution ( public String getName() ) – runs before every getName() of every class.

How to restrict it to a particular class –  @Before execution ( public String org.gaurav.Messenger.getName() ) 

Pointcuts – are the points where advice are supposed to run like before getName().

WildCards – help us to define PointCuts

Advice gets executed only for user defined method execution. It has nothing to do with Springs initialization of Objects. Otherwise you could interfere with the framework.

for all functions beginning with get –

@Before(“execution ( public String get* )”) 

for all functions beginning with get and all return types –

@Before(“execution ( public * get* )”)

for all functions beginning with get, all return types & all scopes –

 @Before(“ execution ( * get* )”) – you could also use  @Before execution (* * get* )

for all functions beginning with get, all return types, all scopes & multiple arguments or if the function takes arguments

 @Before execution ( * get* (*) ) 

for all functions beginning with get, all return types, all scopes & multiple arguments or no arguments

 @Before execution ( * get* (..) ) 

for all functions beginning with get, all return types, all scopes & no arguments

 @Before execution ( * get* () )

For all functions of a class 

 @Before execution (*  * org.gaurav.Messenger.*(..) )

Or

@PointCut (within ( org.gaurav.Messenger )

For all functions of a package

@PointCut (within ( org.gaurav.Messenger. )

For all functions of a package & sub packages

@PointCut (within ( org.gaurav.Messenger.. )

For all functions that have String args

@Before( “args(String)”)

Apply multiple advices to various points?
We can use same annotation before two functions but spring gives a better way to manage

@Before ( f3()  )

Public void f1(){ some lines here }  

@Before ( f3() )

Public void f2(){ some lines here }  

@PointCut ( { EXP} )

Public void f3(){ let this be empty }  

You can chain the pointcuts with conditions

@Before ( EXP1 && EXP2 )

Both functions are dependent on the expression in f3() even if it is empty.

*EXP could also be f1() too

How to get a function name for which the advice is executing on?

EXP

Public void f1( JointCut jc )

{

jc.toString() – returns name of object.

jc.getTarget() – returns object on which it is executing.

}

You can use joint cuts to restrict on how the advice should behave for a particular method.

Types

  1. @Before 
  2. @After 
  3. @AfterReturning 
  4. @Around – acts as both before and after
  5. @AfterThrowing 

Fetch function param in the advice

@Before(“args(name)”)

Public void f1( String name  ) – f1 is advice . The exp tells AOP that it is argument of type String as it is mentioned in the signature – which is passed to the function.

Execute and Fetch function param in the advice whose return type is String 

@AfterReturning(pointcut =“args(name)”, returning=”returnString”)

Public void f1( String name, String  returnString ) 

Execute and  Fetch function param in the advice whose return type is anything

@AfterReturning(pointcut =“args(name)”, returning=”returnString”)

Public void f1( String name, Object returnString ) 

Similarly one can define what advice to run on what exception. @

@Around 

Void f(PRoceedingJointCut p) {

Code before

p.proceed();

Code after

}

Custom Annotations

  1. Define an interface
  2. In the spring.xml 

@Before “@annotation(org.gaurav.mypackage.LoggerCustom)” )

Void advice (){}

3. Using it  

@LoggerCustom
Void f1 ()

All these annotations can be turned to XML binding as well

Spring AOP works on the concept of Proxy objects

Class abc {

Public String f1 {

return “HI”;

}

}

Class abcProvider extends abc {}

Public String f1 {

Run before advice() – injects code based on annotation we provided to AOP

return “HI”;

Run before advice() – injects code based on annotation we provided to AOP

}

}

Spring Data

Spring allows connecting to several databases. Just like JDBC, it also has certain classes that can help to make work easier.

To make a JDBC with Spring class

One can use the same concepts except that Spring can inject the Data Source at run time from the one defined in configuration.

To further the maintainability and availability 

One can use JDBCTemplate.

JDBCTemplatejust needs a DataSource object as a parameter. It takes care of the rest like opening the connection, closing the connection, executing the query etc.

The data source object created in “JDBC with Spring class” can be used and so only a query needs to be set. This does the work of executing the query.

DataSource Is class of type org.springframework.jdbc.datasource.DriverManagerDataSource

To execute Query 

We use function jdbcTemplate.query(…..) ,jdbcTemplate.queryForInt(…..), jdbcTemplate.queryForObject(…..)


The params are like Query String, PArameters, RowMapper

RowMapper is an interface which needs to be implemented in a class.

It maps Resultset to a row/ user defined object.

Like if you are obtaining Student objects in ResultSet (which doesn’t understand the info it is carrying) 

You can easily map the ResultSet data of each row into one object of Student. 

There are various jdbcTemplate classes

  1. jdbcTemplate – for question mark parameters
  2. NamedParameterJdbTemplate – to be used for named parameters.
  3. SimpleJdbcTemplate – Can be used for both the named and question mark parameter

A good way to directly use the jdbc template without having to provide many lines of code in the class is to 

Extends JdbcDaoSupport / SimpleJdbcDaoSupport /..

These classes have no functions to extend but a member variable “DataSource” which needs to be initialized.

The class extending this needs to be provide a data source in bean and then you get the jdbc template prepared object using a getter

this.getJdbcTemplate()

Integrate with Hibernate

One can import the hibernate libraries and import them to integrate the Hibernate with Spring.

Define a SessionFactory bean with required properties  – dataSource, packagesToScan(for any data models) , define hibernate properties (dialect etc).

One does not need a seperate Hibernate.cfg here because spring.xml can be used for the same purpose.

Once SessionFactory which is  a heavy object is constructed – this needs to be done only once – it will be called in any transaction to Open session and execute the query.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *