Modularizing Crosscutting Concerns with Classic

 

AOP defines a group of high-level concepts for application developers to express their crosscutting concerns. First, the crosscutting action to take at a particular execution point is encapsulated in an advice. For example, you can encapsulate the logging and validation actions in one or more advices.

 

Classic Spring AOP supports four types of advices, each of which takes effect at different times of an execution point. In the formal AOP definition, there are many types of execution points, including method executions, constructor executions, and field accesses. However, Spring AOP only supports method executions. So, the definition of the four classic advice types can be narrowed down to the following:

  • Before advice: Before the method execution
  • After returning advice: After the method returns a result
  • After throwing advice: After the method throws an exception
  • Around advice: Around the method execution

How it works?,now let's seeing a simple example:

 

first,define two interfaces:

package cn.cgw.aop;

public interface ArithmeticCalculator {

    public double add(double a, double b);
    public double sub(double a, double b);
    public double mul(double a, double b);
    public double div(double a, double b);
}

 

package cn.cgw.aop;
public interface UnitCalculator {

    public double kilogramToPound(double kilogram);
    public double kilometerToMile(double kilometer);
}
and then,we implement them:
package cn.cgw.aop;

public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

    public double add(double a, double b) {
        double result = a + b;
        System.out.println(a + " + " + b + " = " + result);
        return result;
    }

    public double sub(double a, double b) {
        double result = a - b;
        System.out.println(a + " - " + b + " = " + result);
        return result;
    }

    public double mul(double a, double b) {
        double result = a * b;
        System.out.println(a + " * " + b + " = " + result);
        return result;
    }

    public double div(double a, double b) {
        if (b == 0) {
            throw new IllegalArgumentException("Division by zero");
        }
        double result = a / b;
        System.out.println(a + " / " + b + " = " + result);
        return result;
    }
}

 
package cn.cgw.aop;
public class UnitCalculatorImpl implements UnitCalculator {

    public double kilogramToPound(double kilogram) {
        double pound = kilogram * 2.2;
        System.out.println(kilogram + " kilogram = " + pound + " pound");
        return pound;
    }

    public double kilometerToMile(double kilometer) {
        double mile = kilometer * 0.62;
        System.out.println(kilometer + " kilometer = " + mile + " mile");
        return mile;
    }
}

 

now,we define 4 instance for erery advice:

 

before advice:

public class LoggingBeforeAdvice implements MethodBeforeAdvice {

	private Log log = LogFactory.getLog(this.getClass());
	
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		log.info("The method:" + method.getName() + "()begin with" + Arrays.toString(args));
	}

}
 

After returning advice:

public class LoggingAfterAdvice implements AfterReturningAdvice {

	private Log log = LogFactory.getLog(this.getClass());
	
	public void afterReturning(Object returnValue, Method method, Object[] args,
			Object target) throws Throwable {
		log.info("The method:" + method.getName() + "() end with " + returnValue);
	}

}

 After throwing advice:

public class LoggingThrowsAdvice implements ThrowsAdvice {

	private Log log = LogFactory.getLog(this.getClass());

	public void afterThrowing(Method method, Object[] args, Object target,
			IllegalArgumentException e) throws Throwable {
		log.error("Illegal argument " + Arrays.toString(args) + " for method "
				+ method.getName() + "()");
	}
}
 Around advice: public class LoggingAroundAdvice implements MethodInterceptor {

	private Log log = LogFactory.getLog(this.getClass());

	public Object invoke(MethodInvocation methodInvocation) throws Throwable {
		log.info("The method " + methodInvocation.getMethod().getName()
				+ "() begins with "
				+ Arrays.toString(methodInvocation.getArguments()));
		try {
			Object result = methodInvocation.proceed();
			log.info("The method " + methodInvocation.getMethod().getName()
					+ "() ends with " + result);
			return result;
		} catch (IllegalArgumentException e) {
			log.error("Illegal argument "
					+ Arrays.toString(methodInvocation.getArguments())
					+ " for method " + methodInvocation.getMethod().getName()
					+ "()");
			throw e;
		}
	}

}

 

configuration file:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean id="arithmeticCalculator" class="cn.cgw.aop.ArithmeticCalculatorImpl"/>
    <bean id="unitCalculator" class="cn.cgw.aop.UnitCalculatorImpl"/>
    
    <!-- Advice -->
    <bean id="loggingBeforeAdvice" class="cn.cgw.aop.LoggingBeforeAdvice"/>
    <bean id="loggingAfterAdvice" class="cn.cgw.aop.LoggingAfterAdvice"/>
    <bean id="loggingThrowsAdvice" class="cn.cgw.aop.LoggingThrowsAdvice"/>
    <bean id="loggingAroundAdvice" class="cn.cgw.aop.LoggingAroundAdvice"/>
    
    <!-- AOP Proxy -->
    <bean id="arithmeticCalculatorProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    	<property name="proxyInterfaces">
    		<list>
    			<value>cn.cgw.aop.ArithmeticCalculator</value>
    		</list>
    	</property>
    	<property name="target" ref="arithmeticCalculator"/>
    	<property name="interceptorNames">
    		<list>
    			
    			<value>loggingBeforeAdvice</value>
    			<value>loggingAfterAdvice</value>
    			<value>loggingThrowsAdvice</value>
    			<!-- 
    			<value>loggingAroundAdvice</value>
    			-->
    		</list>
    	</property>
    </bean>
    
    <bean id="unitCalculatorProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    	<property name="proxyInterfaces">
    		<list>
    			<value>cn.cgw.aop.UnitCalculator</value>
    		</list>
    	</property>
    	<property name="target" ref="unitCalculator"/>
    	<property name="interceptorNames">
    		<list>
    			
    			<value>loggingBeforeAdvice</value>
    			<value>loggingAfterAdvice</value>
    			<!-- 
    			<value>loggingAroundAdvice</value>
    			-->
    		</list>
    	</property>
    </bean>

</beans>

 finally,we write a test method:

ApplicationContext context = new ClassPathXmlApplicationContext("beans-aop.xml");
		ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator)context.getBean("arithmeticCalculatorProxy");
		UnitCalculator unitCalculator = (UnitCalculator)context.getBean("unitCalculatorProxy");
		
		arithmeticCalculator.add(1, 2);
        arithmeticCalculator.sub(4, 3);
        arithmeticCalculator.mul(2, 3);
        arithmeticCalculator.div(4, 0);
        unitCalculator.kilogramToPound(10);
        unitCalculator.kilometerToMile(5);
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值