Introducing Spring Framework

Introducing Spring Framework Introducing Spring Framework

25.02.2015 Views

Chapter 8 ■ Give Advice to Your Spring Application } } try{ engineProxy.findByLocation("/some/path/"); }catch(Exception ex){ log.error(ex.getMessage()); } If you run this test with gradle :ch08:test you will have the following output: 2014-02-23 20:04:06,217 DEBUG [main] Using Spring AOP: 2014-02-23 20:04:06,404 ERROR [main] findByLocation not yet implemented. Where are the logs? Well, you removed them from your implementation (see SearchEngineService.java, which is shown in Listing 8-3). You also added a new method in your interface (see Listing 8-2). And in your implementation you just throw an UnsupportedOperationException exception, that’s why you are seeing the error log. Next, let’s learn more about each advice type: before, after, around, and after throw. Before Advice You are going to create your first advice type. Spring AOP provides a MethodBeforeAdvice interface, and it provides a before method for its implementation. This method will be called before the object’s method execution (see Listing 8-6). In other words, you are intercepting a method call before its execution. Listing 8-6. BeforeLoggingModule.java package com.apress.isf.spring.aop; import java.lang.reflect.Method; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.aop.MethodBeforeAdvice; public class BeforeLoggingModule implements MethodBeforeAdvice { private static final Logger log = LoggerFactory.getLogger(BeforeLoggingModule.class); } 96 public void before(Method method, Object[] args, Object target) throws Throwable { if(log.isDebugEnabled()){ log.debug("@@@@(BEFORE) Method called: " + method.getName()); if(args.length ==0 ) log.debug("@@@@(BEFORE) No arguments passed."); for(Object arg:args) log.debug("@@@@(BEFORE) Argument passed:" + arg); } }

Chapter 8 ■ Give Advice to Your Spring Application How will this code interact with your SearchEngine implementation? Well, you only need to declare the BeforeLoggingModule class (see Listing 8-6) in your XML file, as well as declare a Proxy class (I am going to discuss this in the next section). Spring will take care of the rest. Next, you will add the beans you need, as shown in Listing 8-7. Listing 8-7. mydocuments-aop-context.xml beforeLogging You added your beforeLogging bean that points to your class where your interface MethodBeforeAdvice is implemented. Then there is a new bean, engineProxy, that points to the org.springframework.aop.framework. ProxyFactoryBean class. This class will create a proxy using the JDK reflection. Or you can choose to use a CGLib (Code Generation Library) that will help to create the necessary code to be in place when the methods are called. Because here you are using the CGLib, you set the property proxyTargetClass to true. You also defined two more properties, the target that refers to your SearchEngineService class and the property interceptorNames that has the value beforeLogging which matches with your bean definition or your advice. This will help the Spring container to advise all the methods in your SearchEngineService. If you run the same unit test (see Listing 8-5) using gradle :ch08:test you should have the following output: 2014-02-23 20:29:30,119 DEBUG [main] Using Spring AOP: 2014-02-23 20:29:30,152 DEBUG [main] @@@@(BEFORE) Method called: findByType 2014-02-23 20:29:30,152 DEBUG [main] @@@@(BEFORE) Argument passed:Type(name: WEB, description: Web Link, extension: .url) 97

Chapter 8 ■ Give Advice to Your <strong>Spring</strong> Application<br />

How will this code interact with your SearchEngine implementation? Well, you only need to declare the<br />

BeforeLoggingModule class (see Listing 8-6) in your XML file, as well as declare a Proxy class (I am going to discuss<br />

this in the next section). <strong>Spring</strong> will take care of the rest. Next, you will add the beans you need, as shown in Listing 8-7.<br />

Listing 8-7. mydocuments-aop-context.xml<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

beforeLogging<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

You added your beforeLogging bean that points to your class where your interface MethodBeforeAdvice is<br />

implemented. Then there is a new bean, engineProxy, that points to the org.springframework.aop.framework.<br />

ProxyFactoryBean class. This class will create a proxy using the JDK reflection. Or you can choose to use a CGLib<br />

(Code Generation Library) that will help to create the necessary code to be in place when the methods are called.<br />

Because here you are using the CGLib, you set the property proxyTargetClass to true. You also defined two more<br />

properties, the target that refers to your SearchEngineService class and the property interceptorNames that has the<br />

value beforeLogging which matches with your bean definition or your advice. This will help the <strong>Spring</strong> container to<br />

advise all the methods in your SearchEngineService.<br />

If you run the same unit test (see Listing 8-5) using<br />

gradle :ch08:test<br />

you should have the following output:<br />

2014-02-23 20:29:30,119 DEBUG [main] Using <strong>Spring</strong> AOP:<br />

2014-02-23 20:29:30,152 DEBUG [main] @@@@(BEFORE) Method called: findByType<br />

2014-02-23 20:29:30,152 DEBUG [main] @@@@(BEFORE) Argument passed:Type(name: WEB, description:<br />

Web Link, extension: .url)<br />

97

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!