Theinversion Of Control

Print   

02 Nov 2017

Disclaimer:
This essay has been written and submitted by students and is not an example of our work. Please click this link to view samples of our professional work witten by our professional essay writers. Any opinions, findings, conclusions or recommendations expressed in this material are those of the authors and do not necessarily reflect the views of EssayCompany.

As we know that software engineering is remarkably a diverse and widespread application area and Inverting the control is a common design practice in many of the software engineering application areas. This concept has been more popular if we see it in the context of object-oriented application frameworks and the designs which are totally based on the abstract classes or the interfaces. If we talk in the context of Spring which is a light weight container, we can see that dependency injection techniques have once again raised the attention and need of Inversion of control also known as IoC. This name has emerged from the context of object-oriented (OO) applications frameworks. [JF88, Fow04, Fow05] Johnson and Foote have discussed it in terms of designs based on abstract classes. If we see the term inversion that implies a distinction between the application framework, the framework integrating application and the typical direction of control between these two i.e., the application controlling the framework.

Inversion of control means in this context that this direction of control is inverted by some means, allowing the framework to take control over the behavior described by an application, at least partially and in a well-defined manner. If we see this whole context by the structural point of view, this can also be referred as dependency injection.

Introduction:

IoC aka Inversion of Control helps to build loosely coupled software architecture. A software architecture must be highly cohesive and loosely coupled so IoC helps us in architecting such software. It's not pretty much sure whether to call it a design pattern or the approach because if you search around you will find and read a lot of controversial and never ending discussions about it's being design pattern or simply an approach. Well, right now according to my perspective, it's more like a design pattern as it solved problem context. So, let's dig into the more technical details.

Tightly Coupled:

Consider the example as we have a class, called Employee which contains the object of Address class. If you have a little knowledge about the coupling you will see that these two classes are now tightly coupled because the Employee is now totally dependent on the Address object.

public class Employee{

private Address address; // References Problem

public Address(){

address = new Address(); // Awareness of the class

}

}

So, let's assume if the Address class somehow changes, this will lead the modification of Employee class accordingly and the re-compilation as well. So, the problems with this approach are:

→ Employee class handles the instantiation of the Address object.

→ Address is directly referenced in the Employee class that actually leads to tight coupling between both objects.

→ As you can see in the constructor of the Employee class, this class is totally aware of the Address class type and let's say later we need to change the Address class more likely to be OfficeAddress or HomeAddress it will force us to change the Employee class as well because the Employee class is exposed to the actual Address implementation.

Now, as we have seen that the above described scenario has three main problems, so in order to solve them we will try to assign the object creation responsibility to someone else rather than the Employee himself. As we have seen that the main problem arises from the Employee class so if we succeed in assigning the responsibility of instantiation of the Address object to some other class/entity, we actually solve our problem. In other words, we can say that we have inverted the control to a third party. This solution can be called as IOC (Inversion of Control)

There are two very basic principles of the Inversion of Control:

1. Main classes which aggregate other classes should never directly implement the aggregated classes. It will be easier to say it like; both classes should be dependent on abstraction, keeping the real charm of the Object Oriented paradigm. So, how to be dependent on abstraction? I hope you know the answer, as you can use interface or the abstract class to keep the flow of abstraction in your software application.

2. Let's say you have covered the principle 1 somehow but still you must need to have this principle in mind as keeping abstraction only will not fulfill the needs but to keep in mind that the abstraction you have kept in your application should not depend on the details but on the contrary, details should depend upon the abstraction.

Let's understand it with a small example:

Any responsible entity can ask the Employee class to create the Address object for it. The above figure clearly shows how we achieved the decoupling. So, if you see the simplest way of achieving the decoupling is to expose some methods that will allow us send the object and create it. So, now Employee class is not instantiating the Address object itself but rather being called by somewhere else (Let's disclose the secret, IOC Framework) and being created.

So, as now the secret has been disclosed so we discuss a little about IOC Framework. IOC Framework can be a class, a client or any kind of IOC Container. So, it's a two step procedure by which IOC Framework creates the Address object and passes its reference to the Employee class.

Implementation of IOC: So, now as we have seen the problem and somehow managed to fight with it, now let's see the solution in the broader sense. As we have implemented a solution to tackle the problem above, now we try to implement the solution for IOC.

Dependency Injection:

Dependency injection is a software design pattern that allows removing hard-coded dependencies and making it possible to change them, whether at run-time or compile-time. This can be used, for example, as a simple way to load plug-ins dynamically or to choose stubs or mock objects in test environments vs. real objects in production environments. This software design pattern injects the depended-on element (object or value etc) to the destination automatically by knowing the requirement of the destination. Another pattern, called dependency look-up, is a regular process and reverse process to dependency injection. One of its core principles is the separation of behavior from dependency resolution. [1]

Dependency Injection is probably one of the most dead simple design pattern I know. And odds are you have probably already used Dependency Injection. But it is also one of the most difficult one to explain as well. I think it is partly due to the nonsense examples used in most introductions to Dependency Injection. [2]

As we have seen the Dependency Injection, let’s put this in action on, how we actually can implement the IoC using DI.

If you see the figure above, you will see that how IOC and DI are organized, so we can state that IOC is a principle while DI is the way to implement IOC. In DI we have more four ways of implementing the IOC.

1. Constructors

2. Accessors and Mutators

3. Interfaces

4. Service Locators

We will now discuss each one in some detail now.

1. Constructors: In this methodology we pass the object references to the constructor so whenever the client creates object, it passes the object in the constructor and the object gets created. Remember, this methodology is not suited for the clients which can only use the constructors and nothing else.

2. Accessors and Mutators: Often you have heard the term Getters and Setters. All those functions which actually mutate the values into the object are called setters or Mutators and those which allow others to access data are called getters or Accessors. So, this technology is most commonly used by the Dependency Injection. In this methodology, dependent objects are exposed through the accessors and mutators of the classes. The only bad of this methodology is, because the objects are publicly exposed, it breaks the encapsulation rule of object oriented programming.

3. Interfaces: In this methodology we use interface from the IOC framework. IOC Framework will use this interface's methods to inject the object in the main class. If you see in the figure below, we have implemented an interface called AddressDI which has a method setAddress(Address address); which set the Address object. Then later we implemented this interface in the Employee class. Now, external client, containers can use this setAddress method to inject the address object in the Employee object.

4. Service Locators:

The other way to inject dependency is by using service locator. Your main class which will aggregate the child object will use the service locator to obtain instance of the address object. The service locator class does not create instances of the address object, it provides a methodology to register and find the services which will help in creating objects.

Aspect-Oriented Programming in Java

Object oriented programming has become mainstream over the last years, having almost completely replaced the procedural approach. One of the biggest advantages of object orientation is that a software system can be seen as being built of a collection of discrete classes. Each of these classes has a well defined task; its responsibilities are clearly defined. In an OO application, those classes collaborate to achieve the application's overall goal. However, there are parts of a system that cannot be viewed as being the responsibility of only one class, they cross-cut the complete system and affect parts of many classes. Examples might be locking in a distributed application, exception handling, or logging method calls. Of course, the code that handles these parts can be added to each class separately, but that would violate the principle that each class has well-defined responsibilities. This is where AOP comes into play: AOP defines a new program construct, called an aspect, which is used to capture cross-cutting aspects of a software system in separate program entities. The application classes keep their well-defined responsibilities. Additionally, each aspect captures cross-cutting behavior.

This article is divided into three parts: The first part explains the concepts of AOP, the second introduces AspectJ(TM), an implementation of the AOP concepts in Java, and part three compares the AOP approach to metalevel programming.

AOP Basics

Let's introduce AOP with the help of an example. Imagine an application that works concurrently on shared data. The shared data may be encapsulated in a Data object (an instance of class Data). In this application, there are multiple objects of different classes working on a single Data object, whereas only one of these objects may have access to the shared data at a time. To achieve the desired behavior, some kind of locking must be introduced. That means, that whenever one of these objects wants to access the data, the Data object must be locked (and unlocked after the object has finished using it). The traditional approach is to introduce an (abstract) base class, from which all "worker" classes inherit. This class defines a method lock() and a method unlock() which must be called before and after the actual work is done (semaphores, basically). This approach has the following drawbacks:

Every method that works on the data has to take care of locking. The code is cluttered with statements related to locking.

In a single inheritance world, it is not always possible to let all worker classes inherit from a common base class, because the one and only inheritance link may already be consumed by another concept. This is especially true if the locking features must be introduced into a class hierarchy after the hierarchy has been designed, possibly by another programmer (e.g. the developer of a class library).

Reusability is compromised: The worker classes may be reused in another context where they don't need locking (or where they have to use another locking scheme). By putting the locking code into the worker classes, the classes are tied to the locking approach used in this specific application.

The concept of locking in our example application can be described with the following properties:

It is not the primary job of the worker classes

The locking scheme is independent of the worker's primary job

Locking cross-cuts the system, i.e. many classes, and probably many methods of these classes, are affected by locking.

To handle this kind of problems, aspect-oriented programming proposes an alternative approach: A new program construct should be defined that takes care of cross-cutting aspects of a system. Not surprisingly, this new program construct is called an aspect.

In our example application, the aspect Lock would have the following responsibilities:

provide the necessary features to lock and unlock objects to the classes that have to be locked/unlocked (in our example add lock() and unlock() to the Data class)

Ensure that all methods that modify the Data object call lock() before their work and unlock() when they have finished (in our example the worker classes).

What else can aspects do? For example, if a software system needs to log certain method calls (e.g. constructors to track object creation), aspects can help. Here, too, an additional method (log()) is necessary, and this method needs to be called at certain locations in the code. Certainly nobody will waste the inheritance link of completely different classes just to introduce a log() method into the class hierarchy. Here, again, AOP can help by creating an aspect which provides a log() method to the classes that need one, and by calling this method wherever it is required. A third, and quite interesting example might be exception handling. An aspect could define catch() clauses for methods of several classes, thereby enabling consistent exception handling throughout the application.

Two questions arise when looking at aspects: The first is "Are aspects really necessary?" Of course they are not necessary in the sense that a given problem cannot be solved without aspects. But they provide a new, higher level abstraction that might make it easier to design and understand software systems. As software systems become larger and larger, this "understanding" is becoming a major problem. So aspects might prove to be a valuable tool.

A second question could be "But don't aspects break the encapsulation of objects?" Yes somehow they do. But they do so in a controlled way. Aspects have access to the private part of the objects they are associated with. But this doesn't compromise the encapsulation between objects of different classes.

AspectJ

AOP is a concept and as such it is not bound to a certain programming language or programming paradigm. It can help with the shortcomings of all languages that use single, hierarchical decomposition. This may be procedural, object oriented, or functional. AOP has been implemented in different languages, among them Smalltalk and Java. The Java implementation of AOP is called AspectJ (TM) and has been created at Xerox PARC.

Like any other aspect-oriented compiler, the AspectJ compiler includes a weaving phase that unambiguously resolves the cross-cutting between classes and aspects. AspectJ implements this additional phase by first weaving aspects with regular code and then calling the standard Java compiler.

Spring Framework

The Spring Framework provides a comprehensive programming and configuration model for modern Java-based enterprise applications - on any kind of deployment platform. A key element of Spring is infrastructural support at the application level: Spring focuses on the "plumbing" of enterprise applications so that teams can focus on application-level business logic, without unnecessary ties to specific deployment environments.

Spring includes:

Flexible dependency injection with XML and annotation-based configuration styles

Advanced support for aspect-oriented programming with proxy-based and AspectJ-based variants

Support for declarative transactions, declarative caching, declarative validation, and declarative formatting

Powerful abstractions for working with common Java EE specifications such as JDBC, JPA, JTA and JMS

First-class support for common open source frameworks such as Hibernate and Quartz

A flexible web framework for building RESTful MVC applications and service endpoints

Rich testing facilities for unit tests as well as for integration tests

Spring is modular in design, allowing for incremental adoption of individual parts such as the core container or the JDBC support. While all Spring services are a perfect fit for the Spring core container, many services can also be used in a programmatic fashion outside of the container.

Supported deployment platforms range from standalone applications to Tomcat and Java EE servers such as WebSphere. Spring is also a first-class citizen on major cloud platforms with Java support, e.g. on Heroku, Google App Engine, Amazon Elastic Beanstalk and VMware's Cloud Foundry.

The Spring Framework serves as the foundation for the wider family of Spring open source projects, including:

Spring Security

Spring Integration

Spring Batch

Spring Data

Spring Web Flow

Spring Web Services

Spring Mobile

Spring Social

Spring Android

Inversion of Control (IoC)

In software engineering, inversion of control (IoC) is a programming technique, expressed here in terms of object-oriented programming, in which object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis.

In traditional programming, the flow of the business logic is determined by objects that are statically assigned to one another. With inversion of control, the flow depends on the object graph that is instantiated by the assembler and is made possible by object interactions being defined through abstractions. The binding process is achieved through dependency injection, although some argue that the use of a service locator also provides inversion of control.

In order for the assembler to bind objects to one another, the objects must possess compatible abstractions. For example, class A may delegate behavior to interface I which is implemented by class B; the assembler instantiates A and B then injects B to A.

In practice, inversion of control is a style of software construction where reusable code controls the execution of problem-specific code. It carries the strong connotation that the reusable code and the problem-specific code are developed independently, which often results in a single integrated application. Inversion of control as a design guideline serves the following purposes:

There is a decoupling of the execution of a certain task from implementation.

Every module can focus on what it is designed for.

Modules make no assumptions about what other systems do but rely on their contracts.

Replacing modules has no side effect on other modules.

Dependency Injection:

Contexts and Dependency Injection (CDI) for the Java EE platform is one of several Java EE 6 features that help to knit together the web tier and the transactional tier of the Java EE platform. CDI is a set of services that, used together, make it easy for developers to use enterprise beans along with JavaServer Faces technology in web applications. Designed for use with stateful objects, CDI also has many broader uses, allowing developers a great deal of flexibility to integrate various kinds of components in a loosely coupled but type safe way.

CDI is specified by JSR 299, formerly known as Web Beans. Related specifications that CDI uses include the following:

JSR 330, Dependency Injection for Java

The Managed Beans specification, which is an offshoot of the Java EE 6 platform specification (JSR 316)

The most fundamental services provided by CDI are as follows:

Contexts: The ability to bind the lifecycle and interactions of stateful components to well-defined but extensible lifecycle contexts

Dependency injection: The ability to inject components into an application in a typesafe way, including the ability to choose at deployment time which implementation of a particular interface to inject

In addition, CDI provides the following services:

Integration with the Expression Language (EL), which allows any component to be used directly within a JavaServer Faces page or a JavaServer Pages page

The ability to decorate injected components

The ability to associate interceptors with components using type safe interceptor bindings

An event-notification model

A web conversation scope in addition to the three standard scopes (request, session, and application) defined by the Java Servlet specification

A complete Service Provider Interface (SPI) that allows third-party frameworks to integrate cleanly in the Java EE 6 environment

A major theme of CDI is loose coupling. CDI does the following:

Decouples the server and the client by means of well-defined types and qualifiers, so that the server implementation may vary

Decouples the lifecycles of collaborating components by doing the following:

Making components contextual, with automatic lifecycle management

Allowing stateful components to interact like services, purely by message passing

Completely decouples message producers from consumers, by means of events

Decouples orthogonal concerns by means of Java EE interceptors

Along with loose coupling, CDI provides strong typing by

Eliminating lookup using string-based names for wiring and correlations, so that the compiler will detect typing errors

Allowing the use of declarative Java annotations to specify everything, largely eliminating the need for XML deployment descriptors, and making it easy to provide tools that introspect the code and understand the dependency structure at development time

Dependency Injection – The manual way

Dependency injection is a technique that separates behavior from dependency resolution. In simpler words, it allows the developer to define classes with specific functionality that depends on various collaborators, without having to define how reference to these collaborators will be obtained. In that way, decoupling among the various components is achieved and cleaner code is introduced in general. More specifically, instead of hard-coding the dependencies, a component just lists the necessary services and at run-time, an external, independent component will provide access to those services. We should not forget that dependency injection is just a specific form of inversion of control where the concern being inverted is the process of obtaining the needed dependency. The reference article for the aforementioned techniques is "Inversion of Control Containers and the Dependency Injection pattern"

For the purpose of injecting dependencies, a number of frameworks has emerged, the most well-known. However, the use of a whole framework for small projects is undoubtedly an overkill.

Should a Singleton be used only with Dependency Injection Framework?

If accessing a Singleton through getInstance() creates tight coupling, creating an instance of any other class through new() also causes tight coupling. So, how should an object be created maintaining loose coupling?

As per my understanding, Dependency Injection is the answer for both the questions. But, that does not mandate the usage of a framework. Dependency Injection is a concept first and then a framework. When the application under question is small, we can always meet the needs by injecting dependencies manually, without using any framework like Spring.

In any Java application, we repeatedly encounter with two events:

Object creation

Interaction between the objects – The business logic

But, usually we mix up both of them which leads to tight coupling and unwanted dependencies which in turn makes the maintenance as well as unit testing a pain. Let me try to explain it using a very simple example:

class MyClass {

private A a; //A is an interface

private B b; //B is an interface

//Object creation within constructor

MyClass(A a, B b) {

a = new AImpl(); //AImpl is the concrete impl of A

b = new BImpl(); //BImpl is the concrete impl of B

}

//Application logic lies within this method

public void doSomething() {

//Do A specific thing

//Do B specific thing

C c = new CImpl(); //Object creation within the method.

//Do C specific thing

}

}

The Problems with this class is:

It has not been able to separate out the the object creation from the business logic resulting in a tight coupling.

Here "programing to the implementation" has been done, not to interface. Tomorrow, if different implementations of A, B or C is required, the code inside the class has to be changed.

Testing MyClass would require testing of A, B, C first.

Let me try to fix the problem:

class MyClass {

private A a;

private B b;

private C c;

MyClass(A a, B b, C c) {

//Only Assignment

this.a = a;

this.b = b;

this.c = c;

}

//Application Logic

public void doSomething() {

//Do A specific thing

//Do B specific thing

//Do C specific thing

}

}

//The Factory

class MyFactory {

public MyClass createMyClass() {

return new MyClass(new AImpl(), new BImpl(), new CImpl());

}

}

class Main {

public static void main(String args[]) {

MyClass mc = new MyFactory().createMyClass();

mc.doSomething();

}

}

What has been achieved here:

1. Constructor does not have a new():

Objects are not being created within the constructor of MyClass. The constructor is simply being used for field (A, B, C) assignments. Here the constructor asks for the dependencies as parameters, but does not create them (And that is the Simplest definition of dependency injection). However, simple Collection objects like ArrayList, HashMap OR value/leaf objects like Person/Employee (i.e the objects within the application which in turn does NOT create other objects) CAN BE created within the Constructor. Constructor should not be used for any other operation like I/O, thread creation etc.

As a thumb rule, any object should hold references ONLY to other objects whom it needs directly to get it’s work done (This is called the Law of Demeter). For example, if MyClass needs some other class called X, MyClass’ constructor should directly ask for X. It should NOT ask for some other factory F which can return an instance of X. Violation of "Law of Demeter" would result in unwanted dependency between MyClass and F. So, if you find more than one Dot (.) operator be careful – something illegal is happening there.

2. Factory (MyFactory) is taking care of object creation and wiring:

All the new operators (90%-99%) should belong to the factory. It should take care of entire object graph creation for the application and also of relating (wiring) different objects based on their declared dependencies (e.g MyClass needs A, B, C etc). It should not contain anything more – not any other logic (No I/O, thread creation etc).

Tomorrow if C starts depending on something else called D, only C and the factory would be impacted, not the entire object graph (C would have to introduce an overloaded constructor and factory would have to incorporate the object instantiation plus the object wiring related changes).

For a large application of course there may be multiple factories. Here, thumb rule is one factory should instantiate all the objects with same life span.

3. Object creation is separate from the business logic:

MyClass is now a Business Logic Holder. It does not have any new(). Even, it does not have any knowledge about the concrete implementations it is using for the business logic (i.e it knows about A but not about AImpl – "program to interface and not to implementation").

You must have started thinking that I started this discussion with the context of Singleton. How does the manual dependency injection take care of a Singleton? How does it create a Singleton (minus the tight coupling, hidden dependency etc) and access it when needed? Surprisingly, we already have three Singletons in our example – AImpl, BImpl, CImpl. If the factory takes care of creating only one instance of a Class (by invoking new() only once), its a Singleton. Isn’t it? Then the factory may pass that unique instance in the form of dependencies to all other objects those need it.

4. So, where are we? 

MyClass, the business logic holder needs A, B and C for its business. It does not create them but asks for them (the dependencies). The factory (MyFactory) creates those dependencies and wire them to MyClass. But, who creates, the factory? Of course, the main method (the application launcher :-)). Let me repeat the story again, the main method first instantiates the factory, the factory in turn instantiates the object graph, each Object declares their dependencies and finally the main method itself sets the ball rolling – launch the application by invoking doSomething() of MyClass, ie. the objects starts talking to each other executing the usual business.

Let me repeat it once more: Create the factory, create the application using the factory and then start the application! For a large scale application the same thing can be achieved with a Dependency Injection framework like Spring, Google Guice etc. Of course they will come with lot of other benefits, in addition. But, for a small to medium scale application, dependency injection can be hand crafted making the app loosely coupled, more maintainable and of course unit test friendly.

About Beans

CDI redefines the concept of a bean beyond its use in other Java technologies, such as the JavaBeans and Enterprise JavaBeans (EJB) technologies. In CDI, a bean is a source of contextual objects that define application state and/or logic. A Java EE component is a bean if the lifecycle of its instances may be managed by the container according to the lifecycle context model defined in the CDI specification.

More specifically, a bean has the following attributes:

A (nonempty) set of bean types

A (nonempty) set of qualifiers

A scope

Optionally, a bean EL name

A set of interceptor bindings

A bean implementation

A bean type defines a client-visible type of the bean. Almost any Java type may be a bean type of a bean.

A bean type may be an interface, a concrete class, or an abstract class and may be declared final or have final methods.

A bean type may be a parameterized type with type parameters and type variables.

A bean type may be an array type. Two array types are considered identical only if the element type is identical.

A bean type may be a primitive type. Primitive types are considered to be identical to their corresponding wrapper types in java.lang.

A bean type may be a raw type.

About CDI Managed Beans

A managed bean is implemented by a Java class, which is called its bean class. A top-level Java class is a managed bean if it is defined to be a managed bean by any other Java EE technology specification, such as the JavaServer Faces technology specification, or if it meets all the following conditions:

It is not a nonstatic inner class.

It is a concrete class or is annotated @Decorator.

It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in ejb-jar.xml.

It has an appropriate constructor. That is, one of the following is the case:

The class has a constructor with no parameters.

The class declares a constructor annotated @Inject.

No special declaration, such as an annotation, is required to define a managed bean.

Beans as Injectable Objects

The concept of injection has been part of Java technology for some time. Since the Java EE 5 platform was introduced, annotations have made it possible to inject resources and some other kinds of objects into container-managed objects. CDI makes it possible to inject more kinds of objects and to inject them into objects that are not container-managed.

The following kinds of objects can be injected:

(Almost) any Java class

Session beans

Java EE resources: data sources, Java Message Service topics, queues, connection factories, and the like

Persistence contexts (JPA EntityManager objects)

Producer fields

Objects returned by producer methods

Web service references

Remote enterprise bean references

For example, suppose that you create a simple Java class with a method that returns a string:

package users;

public class Users {

public String userName(String name) {

return "Hello, " + name + ".";

}

}

This class becomes a bean that you can then inject into another class. This bean is not exposed to the EL in this form. Giving Beans EL Names explains how you can make a bean accessible to the EL.

Using Qualifiers

You can use qualifiers to provide various implementations of a particular bean type. A qualifier is an annotation that you apply to a bean. A qualifier type is a Java annotation defined as @Target({METHOD, FIELD, PARAMETER, TYPE}) and @Retention(RUNTIME).

For example, you could declare an @Informal qualifier type and apply it to another class that extends the Greeting class. To declare this qualifier type, you would use the following code:

package users;

import static java.lang.annotation.ElementType.FIELD;

import static java.lang.annotation.ElementType.METHOD;

import static java.lang.annotation.ElementType.PARAMETER;

import static java.lang.annotation.ElementType.TYPE;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;

import java.lang.annotation.Target;

import javax.inject.Qualifier;

@Qualifier

@Retention(RUNTIME)

@Target({TYPE, METHOD, FIELD, PARAMETER})

public @interface Informal {}

You can then define a bean class that extends the Users class and uses this qualifier:

package users;

@Informal

public class InformalUsers extends Users {

public String userName(String name) {

return "Hi, " + name + "!";

}

}

Both implementations of the bean can now be used in the application.

If you define a bean with no qualifier, the bean automatically has the qualifier @Default. The unannotated Greeting class could be declared as follows:

package users;

import javax.enterprise.inject.Default;

@Default

public class Users {

public String greet(String name) {

return "Hello, " + name + ".";

}

Injecting Beans

In order to use the beans you create, you inject them into yet another bean that can then be used by an application, such as a JavaServer Faces application. For example, you might create a bean called Printer into which you would inject one of the Users beans:

import javax.inject.Inject;

public class Printer {

@Inject Users users;

...

This code injects the @Default Users implementation into the bean. The following code injects the @Informal implementation:

import javax.inject.Inject;

public class Printer {

@Inject @Informal Users users;

...

More is needed for the complete picture of this bean. Its use of scope needs to be understood. In addition, for a JavaServer Faces application, the bean needs to be accessible through the EL.

Using Scopes

For a web application to use a bean that injects another bean class, the bean needs to be able to hold state over the duration of the user’s interaction with the application. The way to define this state is to give the bean a scope. You can give an object any of the scopes described in Table 28-1, depending on how you are using it.

Table 28-1 Scopes

Scope

Annotation

Duration

Request

@RequestScoped

A user’s interaction with a web application in a single HTTP request.

Session

@SessionScoped

A user’s interaction with a web application across multiple HTTP requests.

Application

@ApplicationScoped

Shared state across all users’ interactions with a web application.

Dependent

@Dependent

The default scope if none is specified; it means that an object exists to serve exactly one client (bean) and has the same lifecycle as that client (bean).

Conversation

@ConversationScoped

A user’s interaction with a JavaServer Faces application, within explicit developer-controlled boundaries that extend the scope across multiple invocations of the JavaServer Faces lifecycle. All long-running conversations are scoped to a particular HTTP servlet session and may not cross session boundaries.

The first three scopes are defined by both JSR 299 and the JavaServer Faces API. The last two are defined by JSR 299.

All predefined scopes except @Dependent are contextual scopes. CDI places beans of contextual scope in the context whose lifecycle is defined by the Java EE specifications. For example, a session context and its beans exist during the lifetime of an HTTP session. Injected references to the beans are contextually aware. The references always apply to the bean that is associated with the context for the thread that is making the reference. The CDI container ensures that the objects are created and injected at the correct time as determined by the scope that is specified for these objects.

You can also define and implement custom scopes, but that is an advanced topic. Custom scopes are likely to be used by those who implement and extend the CDI specification.

A scope gives an object a well-defined lifecycle context. A scoped object can be automatically created when it is needed and automatically destroyed when the context in which it was created ends. Moreover, its state is automatically shared by any clients that execute in the same context.

Java EE components, such as servlets and enterprise beans, and JavaBeans components do not by definition have a well-defined scope. These components are one of the following:

Singletons, such as Enterprise JavaBeans singleton beans, whose state is shared among all clients

Stateless objects, such as servlets and stateless session beans, which do not contain client-visible state

Objects that must be explicitly created and destroyed by their client, such as JavaBeans components and stateful session beans, whose state is shared by explicit reference passing between clients

If, however, you create a Java EE component that is a managed bean, it becomes a scoped object, which exists in a well-defined lifecycle context.

The web application for the Printer bean will use a simple request and response mechanism, so the managed bean can be annotated as follows:

import javax.inject.Inject;

import javax.enterprise.context.RequestScoped;

@RequestScoped

public class Printer {

@Inject @Informal Users users;

Overriding the Scope of a Bean at the Point of Injection

Overriding the scope of a bean at the point of injection enables an application to request a new instance of the bean with the default scope @Dependent. The @Dependent scope specifies that the bean’s lifecycle is the lifecycle of the object into which the bean is injected. The CDI container provides no other lifecycle management for the instance.

Note - The effects of overriding the scope of a bean may be unpredictable or undesirable, especially if the overridden scope is @Request or @Session.

To override the scope of a bean at the point of injection, use the javax.enterprise.inject.New annotation instead of the @Inject annotation. For more information on the @Inject annotation.

Giving Beans EL Names

To make a bean accessible through the EL, use the @Named built-in qualifier:

import javax.inject.Inject;

import javax.enterprise.context.RequestScoped;

import javax.inject.Named;

@Named

@RequestScoped

public class Printer {

@Inject @Informal Users users;

...

The @Named qualifier allows you to access the bean by using the bean name, with the first letter in lowercase. For example, a Facelets page would refer to the bean as printer.

You can specify an argument to the @Named qualifier to use a nondefault name:

@Named("MyPrinter")

With this annotation, the Facelets page would refer to the bean as MyPrinter.

Beans that use session, application, or conversation scope must be serializable, but beans that use request scope do not have to be serializable.

Tutorial Review:

Let us make a complete end-to-end application using Spring 3.0 MVC as front end technology and Hibernate as backend ORM technology. For this application we will also use ANT for build and MySQL as database to persist the data.

The application will be a simple User Login app which will allow user to login to application. The list of users will be displayed and user will be able to update, delete existing contacts if the user is authorized and have admin rights. Otherwise user will be redirected to welcome page.

Our Goal

As describe above, our goal is to create a page which take input from the user for login. If the user has the admin rights he will be able to:

Add new user in the user list.

Display all users from users list.

Delete a user from user list.

If he is not an admin user. He will be landed onto the welcome page.

Application Architecture

We will have a layered architecture for our demo application. The database will be accessed by a Data Access layer popularly called as DAO Layer. This layer will use Hibernate API to interact with database. The DAO layer will be invoked by a service layer. In our application we will have a Service interface called UserService.

Getting Started

For our User Login example, we will use MySQL database. Create table users in any MySQL database. This is very preliminary example and thus we have minimum columns to represent a user. Feel free to extend this example and create a more complex application.

CREATE TABLE `users` (

`user_id` int(5) NOT NULL AUTO_INCREMENT,

`user_name` varchar(50) DEFAULT NULL,

`user_password` varchar(50) DEFAULT NULL,

`user_email` varchar(50) DEFAULT NULL,

`user_authority` varchar(50) DEFAULT NULL,

PRIMARY KEY (`user_id`)

) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

Creating Project in Eclipse

The User Login application will use ANT for build. For this we will use the Dynamic Web Project in Eclipse as the base architecture of our application.

com.xgrid.users.controller; – This package will contain Spring Controller classes for User Login application.

com.xgrid.users.domain; – This package will contain form object for User Login application.

com.xgrid.users.service; – This package will contain code for service layer for our User Login application. The service layer will have one UserService interface and its corresponding implementation class

Entity Class – The Hibernate domain class

Let us start with the coding of User Login application. First we will create a form object or hibernate POJO class to store user information. Also this class will be an Entity class and will be linked with USERS table in database.

Create a java class Users.java under com.xgrid.users.domain package and copy following code into it.

package com.xgrid.users.domain;

import java.io.Serializable;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.Id;

import javax.persistence.Table;

/**

* For a complete reference see

* <a href="http://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single/">

* Hibernate Annotations Communit Documentations</a>

*/

@Entity

@Table(name = "USERS")

public class Users implements Serializable {

private static final long serialVersionUID = -5527566248002296042L;

public Users() {} //not public on purpose!

public Users(int user_id, String user_name, String user_password, String user_email,

String user_authority) {

this.user_id = user_id;

this.user_name = user_name;

this.user_email = user_email;

this.user_password = user_password;

this.user_authority = user_authority;

}

@Id

@Column(name = "USER_ID")

@GeneratedValue

private Integer user_id;

@Column(name = "USER_NAME")

private String user_name;

@Column(name = "USER_PASSWORD")

private String user_password;

@Column(name = "USER_EMAIL")

private String user_email;

@Column(name = "USER_AUTHORITY")

private String user_authority;

public Integer getUser_id() {

return user_id;

}

public void setUser_id(Integer user_id) {

this.user_id = user_id;

}

public String getUser_name() {

return user_name;

}

public void setUser_name(String user_name) {

this.user_name = user_name;

}

public String getUser_password() {

return user_password;

}

public void setUser_password(String user_password) {

this.user_password = user_password;

}

public String getUser_email() {

return user_email;

}

public void setUser_email(String user_email) {

this.user_email = user_email; }

public String getUser_authority() {

return user_authority;

}

public void setUser_authority(String user_authority) {

this.user_authority = user_authority;

}

public static long getSerialversionuid() {

return serialVersionUID;

}

}

The first thing you’ll notice is that the import statements import from javax.persistence rather than a Hibernate or Spring package. Using Hibernate with Spring, the standard JPA annotations work just as well and that’s what I’m using here.

First we’ve annotated the class with @Entity which tells Hibernate that this class represents an object that we can persist.

The @Table(name = "USERS") annotation tells Hibernate which table to map properties in this class to. The first property in this class is our object user_id which will be unique for all events persisted. This is why we’ve annotated it with @Id.

The @GeneratedValue annotation says that this value will be determined by the datasource, not by the code.

The @Column(name = " user_name") annotation is used to map this property to the user_name column in the USERS table.

package com.xgrid.users.controller;

import java.util.List;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

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

import org.springframework.stereotype.Controller;

import org.springframework.validation.BindingResult;

import org.springframework.web.bind.annotation.ModelAttribute;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.servlet.ModelAndView;

import com.xgrid.users.domain.Users;

import com.xgrid.users.service.UsersService;

/**

* Handles and retrieves users request

*/

@Controller

// @RequestMapping("/users")

public class MainController {

protected static Logger logger = Logger.getLogger("controller");

@Autowired

private UsersService usersService;

@RequestMapping("/index")

public ModelAndView listContacts(Map<String, Object> map) {

map.put("users", new Users());

map.put("listUser", usersService.getAll());

ModelAndView modelAndView = new ModelAndView("index");

return modelAndView;

}

@RequestMapping("/welcome")

public ModelAndView welcome() {

ModelAndView modelAndView = new ModelAndView("welcome");

return modelAndView;

}

@RequestMapping(value = "/login", method = RequestMethod.POST)

public String loginUser(@ModelAttribute("users") Users user,

BindingResult result) {

Users loginUser = usersService.isLogin(user.getUser_name(),

user.getUser_password());

if (loginUser != null) {

if (loginUser.getUser_authority().equalsIgnoreCase("admin")) {

return "redirect:userspage.htm";

}

return "redirect:welcome.htm";

}

return "redirect:index.htm";

}

@ModelAttribute("users")

public Users getUserObject() {

return new Users();

}

@RequestMapping(value = "/userspage")

public ModelAndView showUsers(Map<String, Object> map) {

List<Users> userList = usersService.getAll();

map.put("listUser", userList);

ModelAndView modelAndView = new ModelAndView("userspage");

return modelAndView;

}

@RequestMapping(value = "/addUser", method = RequestMethod.POST)

public String add(@ModelAttribute("users") Users user) {

List<Users> userList = usersService.getAll();

usersService.add(user);

System.out.println("User Added");

return "redirect:userspage.htm";

}

@RequestMapping(value = "/deleteUser")

public String delete(HttpServletRequest request,

HttpServletResponse response) {

Integer userId = Integer.parseInt(request.getParameter("userId"));

usersService.delete(userId);

System.out.println("User Added");

return "redirect:userspage.htm";

}

@RequestMapping(value = "/editUser")

public ModelAndView edit(HttpServletRequest request,

HttpServletResponse response, Map<String, Object> map) {

Integer userId = Integer.parseInt(request.getParameter("userId"));

Users user = usersService.get(userId);

map.put("users", user);

ModelAndView modelAndView = new ModelAndView("editpage");

return modelAndView;

}

@RequestMapping(value = "/editUser", method = RequestMethod.POST)

public String edit(@ModelAttribute("users") Users user) {

List<Users> userList = usersService.getAll();

// map.put("listUser", userList);

usersService.edit(user);

System.out.println("User Updated");

return "redirect:userspage.htm";

}

}

package com.xgrid.users.service;

import java.util.Iterator;

import java.util.List;

import javax.transaction.NotSupportedException;

import javax.transaction.SystemException;

import javax.transaction.UserTransaction;

import org.apache.log4j.Logger;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

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

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import com.xgrid.users.domain.Users;

@Service

public class UserServiceImpl implements UsersService{

protected static Logger logger = Logger.getLogger("service");

@Autowired

private SessionFactory sessionFactory ;

private static UserTransaction userTransaction;

Transaction tx = null;

/**

* Retrieves all users

*

* @return a list of users

*/

@Transactional

public List<Users> getAll() {

logger.debug("Retrieving all users");

Session session = sessionFactory.openSession();

String SQL_QUERY = " from Users ";

List<Users> result = (List<Users>)session.createQuery(SQL_QUERY).list();

// Retrieve all

return result;

}

/**

* Retrieves a single users

*/

@Transactional

public Users isLogin(String name, String password) {

//Users user;

try {

Session session = sessionFactory.openSession();

System.out.println("*******************************");

System.out.println("Query using Hibernate Query Language");

// Query using Hibernate Query Language

String SQL_QUERY = " from Users where user_name='"+name+"' and user_password='"+password+"'";

List<Users> result = (List<Users>)session.createQuery(SQL_QUERY).list();

Iterator it = result.iterator();

if(it.hasNext()){

return ((Users)it.next());

}

session.close();

} catch (Exception e) {

System.out.println(e.getMessage());

} finally {

}

return null;

}

/**

* Adds a new users

*/

@Transactional

public void add(Users users) {

logger.debug("Adding new users");

// Retrieve session from Hibernate

try {

Session session = sessionFactory.getCurrentSession();

tx = session.beginTransaction();

session.save(users);

//tx.commit();

} catch (HibernateException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

} catch (IllegalStateException e) {

e.printStackTrace();

}

}

/**

* Deletes an existing users

* @param id the id of the existing users

*/

@Transactional

public void delete(Integer id) {

logger.debug("Deleting existing user");

// Retrieve session from Hibernate

Session session = sessionFactory.getCurrentSession();

// Retrieve existing user first

Users users = (Users) session.get(Users.class, id);

// Delete

session.delete(users);

}

@Transactional

public Users get(Integer id) {

logger.debug("Get existing user by Id");

// Retrieve session from Hibernate

Session session = sessionFactory.getCurrentSession();

// Retrieve existing user first

return (Users) session.get(Users.class, id);

}

/**

* Edits an existing user

*/

@Transactional

public void edit(Users users) {

logger.debug("Updating existing user");

// Retrieve session from Hibernate

try {

Session session = sessionFactory.getCurrentSession();

tx = session.beginTransaction();

session.update(users);

//tx.commit();

} catch (HibernateException e) {

e.printStackTrace();

} catch (SecurityException e) {

e.printStackTrace();

} catch (IllegalStateException e) {

e.printStackTrace();

} }

}

package com.xgrid.users.service;

import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;

import org.hibernate.Query;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import com.xgrid.users.domain.Users;

public interface UsersService {

public List<Users> getAll();

public Users isLogin(String name, String password );

public void add(Users users);

public void delete(Integer id);

public void edit(Users users);

public Users get(Integer id);

}

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

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

<display-name>UserLoginTest</display-name>

<welcome-file-list>

<welcome-file>

index.jsp

</welcome-file>

</welcome-file-list>

<servlet>

<servlet-name>dispatcher</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>dispatcher</servlet-name>

<url-pattern>*.htm</url-pattern>

</servlet-mapping>

<servlet-mapping>

<servlet-name>dispatcher</servlet-name>

<url-pattern>/users/*</url-pattern>

</servlet-mapping>

<servlet-mapping>

<servlet-name>jsp</servlet-name>

<url-pattern>/WEB-INF/jsp/*</url-pattern>

</servlet-mapping>

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

</web-app>

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

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

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

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

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

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

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

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

http://www.springframework.org/schema/context/spring-context-3.0.xsd

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

http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<!-- Activates various annotations to be detected in bean classes -->

<context:annotation-config />

<!-- Scans the classpath for annotated components that will be auto-registered as Spring beans.

For example @Controller and @Service. Make sure to set the correct base-package-->

<context:component-scan base-package="com.xgrid.users.controller" />

<!-- Configures the annotation-driven Spring MVC Controller programming model.

Note that, with Spring 3.0, this tag works in Servlet MVC only! -->

<mvc:annotation-driven />

<!-- Load Hibernate related configuration -->

<import resource="hibernate-context.xml" />

</beans>

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

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

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

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

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

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

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

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

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

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

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

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

http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd

http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd

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

<context:component-scan base-package="com.xgrid.users.controller" />

<context:component-scan base-package="com.xgrid.users.service" />

<bean id="viewResolver"

class="org.springframework.web.servlet.view.InternalResourceViewResolver" >

<property name="prefix">

<value>/WEB-INF/jsp/</value>

</property>

<property name="suffix">

<value>.jsp</value>

</property>

</bean>

<bean id="propertyConfigurer"

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"

p:location="/WEB-INF/spring.properties" />

<bean id="dataSource"

class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"

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

p:url="${jdbc.url}" p:username="${jdbc.username}"

p:password="${jdbc.password}" />

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">

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

<property name="configLocation">

<value>/WEB-INF/hibernate.cfg.xml</value>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

<prop key="hibernate.show_sql">true</prop>

</props>

</property>

<property name="packagesToScan" value="com.xgrid.users.domain"></property>

</bean>

<!--

<bean id="sessionFactory"

class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

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

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">${jdbc.dialect}</prop>

<prop key="hibernate.show_sql">true</prop>

</props>

</propert



rev

Our Service Portfolio

jb

Want To Place An Order Quickly?

Then shoot us a message on Whatsapp, WeChat or Gmail. We are available 24/7 to assist you.

whatsapp

Do not panic, you are at the right place

jb

Visit Our essay writting help page to get all the details and guidence on availing our assiatance service.

Get 20% Discount, Now
£19 £14/ Per Page
14 days delivery time

Our writting assistance service is undoubtedly one of the most affordable writting assistance services and we have highly qualified professionls to help you with your work. So what are you waiting for, click below to order now.

Get An Instant Quote

ORDER TODAY!

Our experts are ready to assist you, call us to get a free quote or order now to get succeed in your academics writing.

Get a Free Quote Order Now