Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Monday, March 2, 2015

Use Spring SimpleJdbcCall to invoke Oracle stored procedure with

Here I would like to show a simple example of using Spring SimpleJdbcCall to invoke one Oracle stored procedure with out parameters as the table of the PL/SQL object.  


Maven

The Oracle database is Oracle 11g and JDBC driver class used ojdbc6-11.2.0.4.jar.  The below is Maven dependency in the project file.
  <dependency>
     <groupId>org.springframework</groupId>
     <artifactId>spring-jdbc</artifactId>
     <version>${spring.version}</version>
  <dependency>
     <groupId>com.oracle</groupId>
     <artifactId>ojdbc6</artifactId>
     <version>11.2.0.4</version>
  </dependency>


Table Schema

The below is DDL for the table BATCH.
  CREATE TABLE "BATCH" 
   ( 
      "ID" NUMBER NOT NULL, 
      "BATCH_NAME" VARCHAR2(256), 
      "BATCH_STATUS" VARCHAR2(20), 
      "LAST_UPDATE_DATE" DATE, 
      "CREATION_DATE" DATE, 
      "LAST_UPDATED_BY" VARCHAR2(100), 
      "CREATED_BY" VARCHAR2(100),
      CONSTRAINT BATCH_PK PRIMARY KEY (ID)
   ) ;


Object Type

In the database one object type: BATCH_REC is defined.
CREATE or REPLACE
TYPE BATCH_REC as OBJECT (
        BATCH_ID NUMBER(10,0), 
        BATCH_NAME VARCHAR2(256), 
        BATCH_STATUS VARCHAR2(20), 
        CREATION_DATE DATE,
 
        INVOICES            INVOICE_TAB
);

CREATE OR REPLACE
TYPE BATCH_TAB IS TABLE OF BATCH_REC; 
/


Stored Procedure

The stored procedure RETRIEVE_BATCH_BY_BATCHSTATUS is shown as below.  This is used to retrieve a list of batches by using batchStatus.  batchStatus is defined as in parameter and batches of type BATCH_TAB as out parameter.
CREATE OR REPLACE PROCEDURE "RETRIEVE_BATCH_BY_BATCHSTATUS" 
  ( 
    batchStatus in BATCH.BATCH_STATUS%TYPE,
    batches out BATCH_TAB,
    p_error_flag out varchar2,
    p_error_code out varchar2,
    p_error_message out varchar2
    ) 
IS 

BEGIN

  batches := BATCH_TAB();
  
  select BATCH_REC(bat.ID,
                   bat.BATCH_NAME,
                   bat.BATCH_STATUS, 
                   bat.VENDOR_SITE_ID,
                   bat.CREATION_DATE,
                   bat.LAST_UPDATE_DATE,
                   bat.LAST_UPDATED_BY,
                   bat.CREATED_BY) 
     bulk collect into batches                
     from BATCH bat where bat.BATCH_STATUS=batchStatus;
  
     p_error_flag := 'N';
   
    EXCEPTION
      WHEN OTHERS THEN
         p_error_code := SQLCODE;
         p_error_message := concat( concat( SQLERRM, '  '), dbms_utility.format_error_backtrace() ); 
         p_error_flag := 'Y';
      
END; 


Spring Class

Here is the DAO class which will use Spring SimpleJdbcCall to invoke the stored procedure: RETRIEVE_BATCH_BY_BATCHSTATUS.  In order to return a list of batches from SimpleJdbcCall there are some points worth to be noticed:  

  1. When declaring out parameter batches, specify its type as Types.ARRAY and also specify its type name as "BATCH_TAB" which is collection type defined in the database.
  2. After the invocation the return value of batches will be casted into the object of oracle.sql.ARRAY, from which the array will be casted into array of Object.
  3. When looping each object in the arry cast each object into oracle.sql.STRUCT.   From the object of STRUCT a list of attributes are obtained.  The values of the attribute match the values of BATCH_REC. 

    
public class BatchDAO {
    private static String PROC_NAME="RETRIEVE_BATCH_BY_BATCHSTATUS";
    
    private static String PARA_BATCHSTUS="batchStatus";
    
    private static String PARA_BATCHES="batches";
    
    private static String PARA_ERROR_FLAG="p_error_flag";
    
    private static String PARA_ERROR_CODE="p_error_code";
    
    private static String PARA_ERROR_MESSAGE="p_error_message";
    
    private SimpleJdbcCall simpleJdbcCall;

    @Autowired
    public void setDataSource(DataSource dataSource) {
        // Set up datasource
        this.simpleJdbcCall = new SimpleJdbcCall(dataSource)
                                  .withProcedureName(PROC_NAME)
                                  .declareParameters(
                                        new SqlParameter(PARA_BATCHSTUS, Types.VARCHAR),
                                        new SqlOutParameter(PARA_BATCHES, Types.ARRAY, "BATCH_TAB"),
                                        new SqlOutParameter(PARA_ERROR_FLAG, Types.VARCHAR),
                                        new SqlOutParameter(PARA_ERROR_CODE, Types.VARCHAR),
                                        new SqlOutParameter(PARA_ERROR_MESSAGE, Types.VARCHAR));
                                        
    }


    public List<Batch> getBatch(String status) throws ScanningException  {
        
        
        SqlParameterSource in = new MapSqlParameterSource().addValue(PARA_BATCHSTUS, status);

        Map<String, Object> out = simpleJdbcCall.execute(status);
        
        List<Batch> batches = new ArrayList<Batch>();
        String errorFlag = (String)out.get(PARA_ERROR_FLAG);
        
        if ( errorFlag.equals("N")) {
            try {
                ARRAY oracleObjectArray = (ARRAY)out.get(PARA_BATCHES);
                Object[] objArr = (Object[])oracleObjectArray.getArray();
                logger.info("Length of retrieved batches from database = "+objArr.length); 
                for (int i=0; i<objArr.length; i++) {
                    STRUCT st = (STRUCT)objArr[i];
                    Object[] obj = st.getAttributes();

                    Batch batch = new Batch();
                    batch.setBatchName((String)obj[1]);
                    batch.setStatus((String)obj[2]);
                    batch.setCreationDate((Date)obj[3]);
                    
                    batches.add(batch);
                }
            } catch (SQLException ex) {
                throw new ScanningException("SQLException occurred.", ex);
            }
        } else {
            String errorCode = (String)out.get(PARA_ERROR_CODE);
            String errorMessage = (String)out.get(PARA_ERROR_MESSAGE);
            
            throw new ScanningException("Exception occurred in "+PROC_NAME);
        }
        
        return batches;
    }
}

Sunday, February 10, 2013

Use Spring MVC Test framework and Mockito to test controllers

Recently I came into one project which is using Spring MVC for web-tier in the architecture.  It gave me a chance to use Spring MVC Test framework and Mockito mock framework together in the unit testing of all Spring MVC controllers in the application.   I found that both of them provide very good functionalities to test the controllers and would like to show what I did with them.

 

Spring MVC Test framework

Before when unit testing MVC controllers we usually use MockHttpServletRequest and MockHttpServletResponse and directly send this mock request to the controllers to do the unit testing, now in Spring 3.2 there is a new test framework which is specially used for testing Spring MVC.   It is Spring MVC Test framework.  With this test framework you can test your controllers just like you test them within a web container but without starting a web container.
Spring MVC Test framework provides much nicer testing framework to cover many aspects of testing in Spring MVC.   With this framework apart from testing business logic within controllers we can also test inbound/outbound request/response serialization (such as JSON request to Java and Java to JSON response), request mapping, request validation, content negotiation, exception handling and etc. 
 In order to use it you can add the below dependency into your project POM file.

    <properties>
        <spring.version>3.2.0.RELEASE</spring.version>
    </properties>
      
    <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>provided</scope>
    </dependency>

The key part of Spring MVC Test framework is MockMVC.  MockMVC will simulate the internals of Spring MVC and MockMVC is the entry point for Spring MVS testing.    
The first step of using Spring MVC testing is to instantiate one instance of MockMVC
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml",
                                                        "classpath:/META-INF/applicationContextForTest.xml"})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class})
public class ProductControllerTest {
   
    @Autowired
    private WebApplicationContext wac;
   
    private MockMvc mockMvc;
   
    @Before
    public void setup() {
        
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();

        // Details are omitted for brevity
    }
}

After MockMVC is created you can use MockMVC to do the testing.    You can create one HTTP request and specify all the details of the request such as HTTP method, content type, request parameters and etc.   Then you can send this request through MockMVC and then verify the results.
RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/welocme");
       
this.mockMvc.perform(requestBuilder).
                        andExpect(MockMvcResultMatchers.status().isOk()).
                        andExpect(MockMvcResultMatchers.model().attribute("welcome_message", "Welcome to use product: DELL Insprson")).
                        andExpect(MockMvcResultMatchers.model().size(1)).
                        andExpect(MockMvcResultMatchers.view().name("welcome"));


Mockito

Mockito is another testing mock framework.   I find that it is quite easy and convenient to use.   First if you want to use it in your project you can the following dependency to your project POM file.  Here I use the version 1.9.5.
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <version>1.9.5</version>
            <scope>test</scope>
        </dependency>

Mockito provides some annotations to simplify writing the testing codes.  @Mock and @InjectMocks are the two annotations I am going to use.   @Mock is used to annotate the object to be mocked.   In the unit testing when testing a method of one object which has the dependency on another object, this dependent object needs to be mocked.  In my project there is class called ProductController and another class ProductService. ProductController uses ProductService to do actual work to serve the requests ProductController is supposed to handle.
@Controller
@RequestMapping("/products")
public class ProductController {
   
    @Autowired
    private ProductService productService;
   
    // Details are omitted for brevity
}

When I test ProductController I have ProductService as mock service so it can mock different responses from ProductService.   Using @Mock annotation from Mockito it can simply be done in my test class as the below:
 @Mock
ProductService mockProductService;

Another step is to put this mock object into the object to be tested.  Mockito provides another very useful annotation @InjectMocks to do. @InjectMocks is to annotate the object where the mock object is injected into.   In my example it is ProductController. and I have the following:
@InjectMocks
ProductController productController;

But in order to make mock object injection really happen there is another thing needed to be done: invoke MockitoAnnotations.initMocks method.  So my test class will be as the below:
public class ProductControllerTest {
   
    @InjectMocks
    private ProductController productController;
   
    @Mock
    private ProductService mockproductService;
   
    @Before
    public void setup() {
       
        MockitoAnnotations.initMocks(this);
    }
}

The basic functions of mock framework is to return a given results when a specific method is invoke.   In Mockito it is done using Mockito.when(...).thenReturn(...) 
public class ProductControllerTest {
   
    @InjectMocks
    private ProductController productController;
   
    @Mock
    private ProductService mockproductService;
   
    @Before
    public void setup() {

        MockitoAnnotations.initMocks(this);

        List<Product> products = new ArrayList<Product>();
        Product product1 = new Product();
        product1.setId(new Long(1));
       
        Product product2 = new Product();
        product2.setId(new Long(2));
       
        products.add(product1);
        products.add(product2);
       
        Mockito.when(mockproductService.findAllProducts()).thenReturn(products);
    }
}

In the above example when findAllProducts method in ProductService is invoked the mocked ProductService will return a list of Products specified before.


Put all together


The below is the code snippet that shows using both Spring MVC Testing and Mockito together for testing a controller.

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml",
                                 "classpath:/META-INF/applicationContextForTest.xml"})
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class})
public class ProductControllerTest {
   
    @Autowired
    private WebApplicationContext wac;
   
    private MockMvc mockMvc;

    @InjectMocks
    private ProductController productController;
   
    @Mock
    private ProductService mockproductService;

   
    @Before
    public void setup() {

        MockitoAnnotations.initMocks(this);

        List<Product> products = new ArrayList<Product>();
        Product product1 = new Product();
        product1.setId(new Long(1));
       
        Product product2 = new Product();
        product2.setId(new Long(2));
       
        products.add(product1);
        products.add(product2);
       
        Mockito.when(mockproductService.findAllProducts()).thenReturn(products);
        
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();

    }

    @Test
    public void testMethod() throws Exception {
       
        List<Product> products = new ArrayList<Product>();
       
        Product product1 = new Product();
        product1.setId(new Long(1));
       
        Product product2 = new Product();
        product2.setId(new Long(2));
       
        products.add(product1);
        products.add(product2);
               
        RequestBuilder requestBuilder = MockMvcRequestBuilders.get("/products");
       
        this.mockMvc.perform(requestBuilder).
                andExpect(MockMvcResultMatchers.status().isOk()).
                andExpect(MockMvcResultMatchers.model().attribute("Products", products)).
                andExpect(MockMvcResultMatchers.model().size(2)).
                andExpect(MockMvcResultMatchers.view().name("show_products"));
       

    }
}







Saturday, February 9, 2013

How Spring MVC works

MVC is a very good design pattern which is widely used in applications with UI(Desktop or web).   In this pattern M is Model, V is the View and C is controller.   The advantage of design pattern is to separate the different responsibilities into 3 parts when dealing UI.   In general terms  Model represents the business data and logic, View is visual part where the data in Model is displayed and Controller is the link of Model and View.  Controller is the brain which decides what data is used and how data is viewed.    Each part in MVC has the clear and dedicated responsibly.   By using MVC pattern the applications with UI become easier to develop, modify and maintain. 


SpringMVC is a web framework provided by Spring based on MVC pattern.   This framework is built on top of JEE/Servlet and is request-driven.  So it means that some servelts will listen on some ports for the incoming request and each request will trigger the whole process of serving this request in MVC and the data or resources that the request asks for is presented.
The below shows the categories of SpringMVC using MVC terms.



In Spring MVC DispatcherServlet and Controllers act as the Controller and they receive the requests and decide how the request will be served and also decide which view is used.  Business objects and domain objects are the Model and the business objects are invoked by the controllers and the all data are in domain objects.   The domain objects will be passed to some JSP which are the View part.  The JSP will render the data in the domain objects.

DisptacherServlet

DispatcherServlet is the front controller in Spring MVC.   It is a HttpServlet that will receive the request and return the response.  DispatcherServlet is the key player in SpringMVC.  From the below brief work flow of SpringMVC you can see DispatcherServlet is the driving force that make the request served with the right response sent back to the client.    


  1. Receive the request from client
  2. Consult HandleMapping to decide which controller processes the request
  3. Dispatch the request to the controller   
  4. Controller processes the request and returns the logical view name and model back to DispatcherServlet
  5. Consult ViewResolver for appropriate View for the logical view name from Controller
  6. Pass the model to View implementation for rendering
  7. View renders the model and returns the result to DispatcherServlet
  8. Return the rendered result from view to the client
It is obvious that DispatcherServlet has a heavy workload.  It needs many other strategy objects and configuration to perform these work.   Each DispatcherServlet has its own specialized ApplicationContext: WebApplicationContext.


MappingHandler


One important work to be done before DispatcherServlet can dispatch the request to the Controller is to find out which controller is right one for this request.  DispatcherServlet uses MappingHandler strategy object to do so.   There are many MappingHandler implementations which uses different strategies to map the request to Controller.   By default DispatcherServlet will use BeanNameUrlHandlerMapping and DefaultAnnotationHandlerMapping.

public interface HandlerMapping {
      HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}


Controller

After the mapping is resolved DispatcherServlet will dispatch the request to the Controller.  Controller does the real work of processing the request.  Also Controller is where programmers need to work most in developing SpringMVC applications.  Controller has the knowledge of processing the request and what logical view be used for different result of request processing.  Usually Controller doesn't do the real processing and it delegates the request processing to the service layer.   Another thing the Controller to do is to package the result of the processing into the Model, which will be rendered in the View finally.


ViewResolver

After the Controller finish the processing of request it will return the logical view name and the data to DispatcherServlet, which will decide the actual view to be used since the view name from Controller is logical name.   With the help of ViewResolver strategy object DispatcherServlet can find out physical view from the logical view name.   Similar to MappingHandler there are also many different strategies  for resolving the view based on the different view technologies.    Most commonly used implementation of ViewResolver is InternalResourceViewResolver.  

public interface ViewResolver {
      View resolveViewName(String viewName, Locale locale) throws Exception;
}


View

View is where the data in the Model is rendered as the required output for the client.   SpringMVC provides many implementations of View to generate different output such as JSP,Excel, PDF, XML and etc.   DispatcherServlet will invoke render method from selected View implementation to generate the output to be returned to the client.

public interface View {
      String getContentType();
      void render(Map<String, ?> model, HttpServletRequest request,  HttpServletResponse response) throws Exception;
}

Friday, February 8, 2013

Root WebApplicationContext and Child WebApplicationContext

SpringMVC uses one special ApplicationContext: WebApplicationContext in web application.   WebApplicationContext is the extension of ApplicationContext.   It has ServletContext and and beans in WebApplicationContext can access ServletContext if they implement the interface ServletContextAware.

In Spring ApplicationContext can be hierarchical.  One ApplicationContext can have multiple child ApplicationContext and can only have one parent.   Beans in child ApplicationContext can access the beans in parent.

In SpringMVC each DispatcherServlet has one WebApplicationContext.   So there may be more than WebApplicationContext if the web application has multiple DispatcherServlet. By default Spring always look for the ApplicationContext: your_dispatcherservlet_name-servlet.xml. These DispatcherServlet related WebApplicationContext should have MVC-specific configurations.   Other non MVC-specific configuration such as the beans for service or persistence layer should be in root WebApplicationContext.

In SpringMVC the root WebApplicationContext is bootstrapped by using ContextLoadListener specified as Listener in web.xml.



<web-app>
              ............
            <context-param>
                        <param-name>contextConfigLocation</param-name>
                        <param-value>
                                    /WEB-INF/classes/META-INF/applicationContext.xml
                                    /WEB-INF/classes/META-INF/applicationSecurity.xml
                        </param-value>

            </context-param>

            <listener>
                        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
            </listener>
              ............
</web-app>


The above is the example of configuration in web.xml for root WebApplicationContext.

MVC specific WebApplicationContext is loaded for each of DispatcherServlet.  It is defined in each of servlet in web.xml. The below is an example of configuration for a DispatcherServelt where a child WebApplicationContext is specified.



<web-app>
            ...........
.
            <servlet>
                        <servlet-name>mvc-dispatcher</servlet-name>
                        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                <init-param>
                    <param-name>contextConfigLocation</param-name>
                    <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
                </init-param>
                <load-on-startup>1</load-on-startup>
            </servlet>

            ............
</web-app>



Saturday, January 21, 2012

Spring AOP Tutorial


Spring AOP Tutorial

OOP vs. AOP
Just like OOP which is widely used to design application by modularizing core business functionalities of the application into objects AOP is used to modularize the cross-cutting concerns of the application into aspects. From OOP perspective one application system is consisted of many objects and each object encapsulates some core functionality of the system. But apart from these core business functionalities in the objects there are still non core functionalities in one system. These functionalities or requirements cannot easily be represented in objects because these such as logging, security or transaction management are scattered in various objects. If these functionalities are represented in objects there will be lots of duplicates of the codes spread in the objects. An elegant representation of these scattered or cross-cutting functionalities or concerns is needed and thus here comes AOP. AOP provides another perspective to the application system. In AOP these cross-cutting concerns are represented as aspects and then the aspects are applied to the objects or objects are advised with the aspects. OOP and AOP are complimented each other. 

Benefits of Using AOP
With AOP the cross-cutting concerns can be modularized into aspects. Now the codes that implement the cross-cutting concerns are in one place: aspect. And aspect can be applied to any place where these concerns are needed. The core business objects just need to have the codes for primary business logic. All the codes of one application are better organized. 


There are several ways to implement Spring AOP.

1.      One way is to create the aspect from a POJO by implementing some AOP advice interfaces.   These interfaces are:

org.springframework.aop.MethodBeforeAdvice
org.springframework.aop.AfterReturningAdvice
org.springframework.aop.ThrowsAdvice


public class LoggingAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {

    public void before(Method method, Object[] os, Object o) throws Throwable {
        System.out.println("LoggingAdvice before is invoked.");
    }

    public void afterReturning(Object o, Method method, Object[] os, Object o1) throws Throwable {
        System.out.println("LoggingAdvice afterReturning is invoked.");
    }

    public void afterThrowing(Exception ex) {
        System.out.println("LoggingAdvice afterThrowing is invoked.");
    }
}

Advice defines what (printing some message here) and when (before the method invocation, after method invocation and etc.) to do in an aspect.   Further we need to specify where this advice will be applied to.  That is: which method is the advice applied to.  These are the works of pointcut which defines a set of joint points where the advice is applied to.

<bean id="loggingAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="advice" ref="loggingAdvice"/>
        <property name="pointcut" ref="loggingPointcut"/>
 </bean>

 <bean id="loggingPointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
        <property name="expression" value="execution(* *.add*(..))"/>
 </bean>

<bean id="loggingAdvice" class="com.toic.spring3.cert.aop.LoggingAdvice"/>

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>


2.      Another way of creation of aspect is to use @AspectJ annotation with POJO when using Java 5 or higher.

In this way a POJO can be defined as an aspect using some annotations such as @AspectJ, @Before, @After and etc.  

@Aspect
public class LoggingAspect {

    @Before("execution(* com.toic.spring3.aop.demo.ResourceServiceImpl.addResource(..))")
    public void logBefore(JoinPoint joinPoint) {

        System.out.println("logBefore() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println();
    }

    @After("execution(* com.toic.spring3.aop.demo.ResourceServiceImpl.addResource(..))")
    public void logAfter(JoinPoint joinPoint) {

        System.out.println("logAfter() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println();
    }

    @AfterReturning(
        pointcut = "execution(* com.toic.spring3.aop.demo.ResourceServiceImpl.addResource(..))",
        returning= "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {

        System.out.println("logAfterReturning() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("Method returned value is : " + result);
        System.out.println();
    }
   
    @AfterThrowing(
        pointcut = "execution(* com.toic.spring3.aop.demo.ResourceServiceImpl.addResourcceThrowException(..))",
        throwing= "error")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {

        System.out.println("logAfterThrowing() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("Exception : " + error);
        System.out.println();
    }
   
    @Around("execution(* com.toic.spring3.aop.demo.ResourceServiceImpl.addResource(..))")
    public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {

                System.out.println("logAround() is running!");
                System.out.println("hijacked method : " + joinPoint.getSignature().getName());
                System.out.println("hijacked arguments : " + Arrays.toString(joinPoint.getArgs()));

                System.out.println("Around before is running!");
        System.out.println();
       
                joinPoint.proceed(); //continue on the intercepted method
       
                System.out.println("Around after is running!");

                System.out.println();

   }

<aop:aspectj-autoproxy />

<bean id="customerBo" class="com.toic.spring3.aop.demo.ResourceServiceImpl" />

<!-- Aspect -->
<bean id="logAspect" class="com.toic.spring3.aop.demo.LoggingAspect" />


3.      There is another way to create aspect.  Spring provides schema-based AOP support so if you prefer to use XML configuration instead of annotations.   You can choose this way.  One of the greatest advantage of this ways is that you can turn any POJO into an aspect.  This POJO needs no special interfaces or annotations.

public class LoggingAspect {

    public void logBefore(JoinPoint joinPoint) {

        System.out.println("logBefore() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println();
    }

    public void logAfter(JoinPoint joinPoint) {

        System.out.println("logAfter() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println();
    }
}


In the XML configuration you can define an aspect from the POJO using Spring AOP configuration elements.   In the below example under <aop:config> there is one aspect whose id is aspectLogging defined.

<aop:aspectj-autoproxy />

 <bean id="resourceService" class="com.toic.spring3.aop.demo.ResourceServiceImpl" />

<!—POJO class -->
<bean id="logAspect" class="com.toic.spring3.aop.demo.LoggingAspect" />

<aop:config>

      <aop:aspect id="aspectLogging" ref="logAspect" >
            
             <aop:pointcut id="pointCutBefore"
                expression="execution(* com.toic.spring3.aop.demo.ResourceServiceImpl.addResource(..))" />

             <aop:before method="logBefore" pointcut-ref="pointCutBefore" />
            
             <aop:pointcut id="pointCutAfter"
                expression="execution(* com.toic.spring3.aop.demo.ResourceServiceImpl.addResource(..))" />
               
             <aop:after method="logAfter"  pointcut-ref="pointCutAfter" />
       </aop:aspect>

 </aop:config>