Spring-AOP
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </dependency>
Instead of maintaining business logic and services logic together, develop services and business logic separately. Inject those services in to Business class using AOP
Maintaining Service logic separately from Business logic
Services are like Transaction Services, Security, Mailing, JMS Services
Aspect is nothing but a Service
Advice is nothing but a ServiceProvider. By using Advice you can provide ASPECT
PointCut is nothing but a point or condition to execute aspects for your business methods.
Adviser is nothing but pointcut with advice combination
Proxy is a waiver (proxy object will be generated by combining service and business code)
target is nothing but businees object
We can implement in 3 approaches
Programatic approach
Declarative approach
Annotation approach
Programatic approach
org.springframework.aop.MethodBeforeAdvice;
org.springframework.aop.AfterReturningAdvice;
org.springframework.aop.ThrowsAdvice;
org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor;
Programatic approach:
public class LoggingBefore implements MethodBeforeAdvice{ Logger log = LoggerFactory.getLogger(LoggingBefore.class); @Override public void before(Method method, Object[] objects, Object o) throws Throwable { log.debug("before calling enrollStudent method"); log.debug(method.getName()); log.debug(objects.toString()); } }
Client Class:
//create target BankServiceImpl bsi = new BankServiceImpl(); //create advice LogBeforeService lbs = new LogBeforeService() //generating proxy by combining target + advice ProxyFactoryBean pfb = new ProxyFactoryBean(); pfb.setTarget(bsi); pfb.addAdvice(loggingBefore); //get generated proxy object BankServiceImpl bsi =(BankServiceImpl)pfb.getObject();
Declarative approach
<!--Target --> <bean id="stdImpl" class="com.springapp.mvc.service.EnrollStudentServiceImpl"/> <!-- advice --> <bean id="logBef" class="com.springapp.mvc.aop.LoggingBefore"/> <!-- proxyBean--> <bean id="proxyStudentImpl" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="stdImpl"/> <property name="interceptorNames"> <list> <value>logBef</value> </list> </property> </bean>
Pointcuts : If you want to specify where exactly service need to be executed then we can use pointcut
StaticMethodMatcherPointcut
NameMatchMatcherPointcut
public class EnrollPointCut extends StaticMethodMatcherPointcut { @Override public boolean matches(Method method, Class<?> aClass) { if(method.getName().equals("enrollStudent")){ return true; } return false; } }
Advicer:
DefaultPointcutAdvicer
RegexpMethodPointcutAdvicer
<!--Target --> <bean id="stdImpl" class="com.springapp.mvc.service.EnrollStudentServiceImpl"/> <!-- advice --> <bean id="logBef" class="com.springapp.mvc.aop.LoggingBefore"/> <!-- pointCut --> <bean id="enrollPointCut" class ="com.springapp.mvc.aop.EnrollPointCut"/> <!-- Advisor --> <bean id="dpa" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice" ref="logBef"/> <property name="pointcut" ref="enrollPointCut"/> </bean> <!-- proxyBean--> <bean id="proxyStudentImpl" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="stdImpl"/> <property name="interceptorNames"> <list> <value>dpa</value> </list> </property> </bean>