一.什么是面向切面

AOP 是Aspect-Oriented Programming的简称,意思是面向切面编程。AOP是对OOP的补充和完善。比如刚才的问题,程序中所有的业务方法都需要日志记录、参数验证、事务处理,这些公共的处理如果放在每个业务方法里,系统会变的臃肿,而且很难去维护。散布在系统各处的需要在实现业务系统时关注的事情就被成为“切面”,也称为关注点,AOP的思想就是把这些公共部分从业务方法中提取出来,集中处理。

<aop:config>

设置切面

<aop:pointcut>

设置切点

<aop:aspect>

引入增强bean

<aop:after-throwing>

异常增强

<aop:after>

后置增强

<aop:before>

前置增强

<aop:around>

环绕增强

<!--配置切点-->
    <!--对哪一个类或者哪一个方法进行值的注入,第二个参数是对哪一个类进行值的注入-->
    <!--(* com.offcn.service.UserService.*(..))代表userService所有方法-->
  <aop:pointcut id="pointcut" expression="execution(* com.offcn.service.UserService.*(..))"></aop:pointcut>

  <!--引入方法的增强bean-->
    <aop:aspect ref="aopError">


  <!--在这个里面也就可以配置你的异常后置增强,这个方法必须引入你的增强bean的方法-->
  <!--第二个参数是设置切点-->
<aop:after-throwing method="afterError" pointcut-ref="pointcut" throwing="e"></aop:after-throwing>

  <!--环绕增强  相当于一个前置+一个后置-->
<aop:around method="around" pointcut-ref="pointcut"></aop:around>

 <!--配置切点-->
    <!--对哪一个类或者哪一个方法进行值的注入,第二个参数是对哪一个类进行值的注入-->
    <!--(* com.offcn.service.UserService.*(..))代表userService所有方法-->
  <aop:pointcut id="pointcut" expression="execution(* com.offcn.service.UserService.*(..))"></aop:pointcut>

  <!--引入方法的增强bean-->
    <aop:aspect ref="aopError">


  <!--在这个里面也就可以配置你的异常后置增强,这个方法必须引入你的增强bean的方法-->
  <!--第二个参数是设置切点-->
<aop:after-throwing method="afterError" pointcut-ref="pointcut" throwing="e"></aop:after-throwing>

  <!--环绕增强  相当于一个前置+一个后置-->
<aop:around method="around" pointcut-ref="pointcut"></aop:around>

二.面向切面的编程

面向切面原生态开发(需要自己配置xml)
这个原生态的增强bean

package com.offcn.aop;

import  org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.Arrays;

public class AopError  {
    /*JoinPoint这个类封装了所有动态代理的类的信息*/
    public void afterError(JoinPoint joinpoint, RuntimeException e){
        System.out.println(joinpoint.getSignature().getName()+"这个方法的异常信息"+e.getMessage());
    }

    public void  after(JoinPoint joinPoint){
        System.out.println(joinPoint.getSignature().getName());

    }
    /*环绕增强   传递的是JoinPoint的一个子类ProceedingJoinPoint*/
    public void around(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println(proceedingJoinPoint.getTarget()+Arrays.toString(proceedingJoinPoint.getArgs()));

        try {
            //调用此方法执行目标对象的相应方法,这个方法相当于一个分割线,
            proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println(proceedingJoinPoint.getSignature().getName());

    }
}


package com.offcn.aop;

import  org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.Arrays;

public class AopError  {
    /*JoinPoint这个类封装了所有动态代理的类的信息*/
    public void afterError(JoinPoint joinpoint, RuntimeException e){
        System.out.println(joinpoint.getSignature().getName()+"这个方法的异常信息"+e.getMessage());
    }

    public void  after(JoinPoint joinPoint){
        System.out.println(joinPoint.getSignature().getName());

    }
    /*环绕增强   传递的是JoinPoint的一个子类ProceedingJoinPoint*/
    public void around(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println(proceedingJoinPoint.getTarget()+Arrays.toString(proceedingJoinPoint.getArgs()));

        try {
            //调用此方法执行目标对象的相应方法,这个方法相当于一个分割线,
            proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println(proceedingJoinPoint.getSignature().getName());

    }
}

这是原生态.XML文件

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<!--配置dao层-->
<bean id="userDao" class="com.offcn.dao.impl.UserDaoImpl"></bean>
<!--配置service层-->
<bean id="userService" class="com.offcn.service.impl.UserServiceImpl">
    <property name="userDao" ref="userDao"></property>
</bean>
<!--配置增强的bean-->
<bean id="aopError" class="com.offcn.aop.AopError"></bean>
<!--设置切面-->
<aop:config>
    <!--配置切点-->
    <!--对哪一个类或者哪一个方法进行值的注入,第二个参数是对哪一个类进行值的注入-->
    <!--(* com.offcn.service.UserService.*(..))代表userService所有方法-->
    <aop:pointcut id="pointcut" expression="execution(* com.offcn.service.UserService.*(..))"></aop:pointcut>
    <!--引入方法的增强bean-->
    <aop:aspect ref="aopError">
        <!--在这个里面也就可以配置你的异常后置增强,这个方法必须引入你的增强bean的方法-->
        <!--第二个参数是设置切点-->
     <!--   <aop:after-throwing method="afterError" pointcut-ref="pointcut" throwing="e"></aop:after-throwing>-->
        <!--后置增强-->
       <!-- <aop:after method="after" pointcut-ref="pointcut"></aop:after>-->
        <!--前置增强-->
      <!--  <aop:before method=""></aop:before>-->
        <!--环绕增强  相当于一个前置+一个后置-->
       <aop:around method="around" pointcut-ref="pointcut"></aop:around>
    </aop:aspect>

</aop:config>
</beans>

有注解的是已经包装过得(xml中就不需要再自己配置)
这是使用注解的增强bean

package com.offcn.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import java.util.Arrays;
@Aspect
public class AopError {
 /*这个类封装了所有动态代理的类的信息*//*
    //expression="execution(* com.offcn.service.UserService.*(..)

   //@AfterThrowing(pointcut = "(* com.offcn.service.UserService.*(..))",throwing = "e")
    public void afterError(JoinPoint joinpoint, RuntimeException e){
        System.out.println(joinpoint.getSignature().getName()+"这个方法的异常信息"+e.getMessage());
    }
    
   public void after(JoinPoint joinPoint){
        System.out.println(joinPoint.getSignature().getName());

    }
*/

    /*环绕增强 传递的是其JoinPoint子类ProceedingJoinPoint*/
    @Around("execution(* com.offcn.service.UserService.*(..))")
    public  void  around(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println(proceedingJoinPoint.getTarget()+ Arrays.toString(proceedingJoinPoint.getArgs()));
        /*调用此方法执行目标对象相应的方法*//**//*这个方法又相当于一个分割线,也就是前置与后置的分割线*/
        try {
            proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }       System.out.println(proceedingJoinPoint.getSignature().getName());
    }
}


//需要添加的jar包
aopalliance-1.0.jar
aspectjweaver-1.6.9.jar
cglib-nodep-3.1.jar
commons-logging-1.2.jar
junit-4.10.jar
log4j-1.2.17.jar
spring-aop-3.2.13.RELEASE.jar
spring-beans-3.2.13.RELEASE.jar
spring-context-3.2.13.RELEASE.jar
spring-core-3.2.13.RELEASE.jar
spring-expression-3.2.13.RELEASE.jar

package com.offcn.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import java.util.Arrays;
@Aspect
public class AopError {
 /*这个类封装了所有动态代理的类的信息*//*
    //expression="execution(* com.offcn.service.UserService.*(..)

   //@AfterThrowing(pointcut = "(* com.offcn.service.UserService.*(..))",throwing = "e")
    public void afterError(JoinPoint joinpoint, RuntimeException e){
        System.out.println(joinpoint.getSignature().getName()+"这个方法的异常信息"+e.getMessage());
    }
    
   public void after(JoinPoint joinPoint){
        System.out.println(joinPoint.getSignature().getName());

    }
*/

    /*环绕增强 传递的是其JoinPoint子类ProceedingJoinPoint*/
    @Around("execution(* com.offcn.service.UserService.*(..))")
    public  void  around(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println(proceedingJoinPoint.getTarget()+ Arrays.toString(proceedingJoinPoint.getArgs()));
        /*调用此方法执行目标对象相应的方法*//**//*这个方法又相当于一个分割线,也就是前置与后置的分割线*/
        try {
            proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }       System.out.println(proceedingJoinPoint.getSignature().getName());
    }
}


//需要添加的jar包
aopalliance-1.0.jar
aspectjweaver-1.6.9.jar
cglib-nodep-3.1.jar
commons-logging-1.2.jar
junit-4.10.jar
log4j-1.2.17.jar
spring-aop-3.2.13.RELEASE.jar
spring-beans-3.2.13.RELEASE.jar
spring-context-3.2.13.RELEASE.jar
spring-core-3.2.13.RELEASE.jar
spring-expression-3.2.13.RELEASE.jar

这是使用注解的.XML文件,多了三个AOP的头

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
	http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.2.xsd
    http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

	<context:component-scan base-package="com.offcn.service,com.offcn.dao" />
	<bean class="com.offcn.aop.AopError"></bean>
	<!--开启spring注解-->
	<aop:aspectj-autoproxy/>
</beans>

注解的解释:
@Aspect :注解表示这是一个切面
@AfterThrowing:注解表示异常增强

@AfterThrowing(pointcut = "(* com.offcn.service.UserService.*(..))",throwing = "e")

@AfterThrowing(pointcut = "(* com.offcn.service.UserService.*(..))",throwing = "e")

@After @Before @Around:注解表示后置,前置,环绕增强

//execution表示切入点指示符
@After("execution(* com.offcn.service.UserService.*(..))")
@Before("execution(* com.offcn.service.UserService.*(..))")
@Around("execution(* com.offcn.service.UserService.*(..))")

//execution表示切入点指示符
@After("execution(* com.offcn.service.UserService.*(..))")
@Before("execution(* com.offcn.service.UserService.*(..))")
@Around("execution(* com.offcn.service.UserService.*(..))")