首页 > 代码库 > Spring4的学习(二)之AOP编程

Spring4的学习(二)之AOP编程

1. AOP 简介

AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面向对象编程) 的补充.


AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点.


在应用 AOP 编程时, 仍然需要定义公共功能, 但可以明确的定义这个功能在哪里, 以什么方式应用, 并且不必修改受影响的类. 这样一来横切关注点就被模块化到特殊的对象(切面)里.


AOP 的好处:

    ---每个事物逻辑位于一个位置, 代码不分散, 便于维护和升级

    ---业务模块更简洁, 只包含核心业务代码.


2. AOP的术语和图形表达

      

切面(Aspect):  横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象

通知(Advice):  切面必须要完成的工作

目标(Target): 被通知的对象

代理(Proxy): 向目标对象应用通知之后创建的对象

连接点(Joinpoint):程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。例如 ArithmethicCalculator#add() 方法执行前的连接点,执行点为 ArithmethicCalculator#add(); 方位为该方法执行前的位置

切点(pointcut):每个类都拥有多个连接点:例如 ArithmethicCalculator 的所有方法实际上都是连接点,即连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。


3.在spring4中如何使用AOP?

   ①首先我们要做的还是先导入一系列架包。导入完以后右击buildpath引用下,如下:

     

    ②写一个含有+-*%方法的接口,并写好他的实现类代码如下:

        1.ArithmeticCalculator(接口)

     

package com.icss.spring.aopimpl;

public interface ArithmeticCalculator {

	int add(int i, int j);
	int sub(int i, int j);
	
	int mul(int i, int j);
	int div(int i, int j);
	
}
        2.实现类,记得在实现类上面加上注解交给spring来管理

    

package com.icss.spring.aopimpl;
import org.springframework.stereotype.Component;

@Component("arithmeticCalculator")
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

	public int add(int i, int j) {
		int result = i + j;
		return result;
	}

	public int sub(int i, int j) {
		int result = i - j;
		return result;
	}

	public int mul(int i, int j) {
		int result = i * j;
		return result;
	}

	public int div(int i, int j) {
		int result = i / j;
		return result;
	}

}
         3.先写一个main函数来测试下,此时直接输出result=12,结果前后并没有打印日志记录,我们需要做的就是要让结果前后显示日志记录。

package com.icss.spring.aopimpl;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("aop.xml");
        ArithmeticCalculator  arithmeticCalculator= applicationContext.getBean(ArithmeticCalculator.class);
        int result = arithmeticCalculator.add(3, 9);
        System.out.println("result = "+result);
	}

}

        4.下面写一个loggingAspect日志切面(AOP编程)

  

package com.icss.spring.aopimpl;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LoggingAspect {
    
	@Before("execution(public int com.icss.spring.aopimpl.ArithmeticCalculatorImpl.add(int , int ))")
	 public void beforeMethod() {
		 System.out.println("add方法执行之前打印出来");
	}
}

@Before("execution(public int com.icss.spring.aopimpl.ArithmeticCalculatorImpl.add(int , int ))")

这句话的意思就是我们需要明确的指出,这个方法需要在哪个方法执行之前,也可以使用通配符*,来让所有的方法之前都执行这个方法。


  5.最后一步就是我们要配置下aop.xml文件,让他自动生成代理对象,执行main就ok了!特别注意xmls!!!上面的命名空间,千万不要忘了加!不然没用!!!!

 

<?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:aop="http://www.springframework.org/schema/aop"
	xmlns:context="http://www.springframework.org/schema/context"
	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-4.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
	
   <context:component-scan base-package="com.icss.spring.aopimpl"></context:component-scan>
   <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
	
	
</beans>

     6.我们想要的结果如下:(这里只写了前置通知的方法,后置通知大家可以自己试试!)

  

    7.大家还可以在通知方法中声明一个类型为 joinpoint的参数,然后就能访问连接细节了,如方法名和参数值!代码如下: