Spring的学习(十二)——SpringAOP

一、基于xml

需要导入jar包:aopalliance.jar、aspectjweaver.jar、spring-aop-x.x.x.RELEASE.jar、spring-aspects-x.x.x.RELEASE.jar

建立User:

package com.little.entity;
public class User {

    private int uid;
    private String uname;

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }
}

建立UserService接口:

package com.little.service;

import com.little.entity.User;

public interface UserService {

    // 添加 user
    public void addUser(User user);

    // 删除 user
    public void deleteUser(int uid);
}

实现UserServiceImpl接口:

package com.little.service.impl;

import com.little.entity.User;
import com.little.service.UserService;

public class UserServiceImpl implements UserService {

    public void addUser(User user) {
        System.out.println("增加 User");
    }

    public void deleteUser(int uid) {
        System.out.println("删除 User");
    }
}

建立通知类:

package com.little.adivce;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAdivce {

    /**
     //前置通知:目标方法运行之前调用
     //后置通知(如果出现异常不会调用):在目标方法运行之后调用
     //环绕通知:在目标方法之前和之后都调用
     //异常拦截通知:如果出现异常,就会调用
     //后置通知(无论是否出现 异常都会调用):在目标方法运行之后调用
     */

    // 前置通知
    public void before() {
        System.out.println("这是前置通知");
    }

    // 后置通知
    public void afterReturning() {
        System.out.println("这是后置通知(方法不出现异常)");
    }

    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("这是环绕通知之前部分!!");
        Object object = point.proceed(); // 调用目标方法
        System.out.println("这是环绕通知之后的部分!!");
        return object;
    }

    public void afterException() {
        System.out.println("异常通知!");
    }

    public void after() {
        System.out.println("这也是后置通知,就算方法发生异常也会调用!");
    }
}

配置applicationContext-aop.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans" 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-4.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.2.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">

    <bean name="userService" class="com.little.service.impl.UserServiceImpl" />

    <!--配置通知对象 -->
    <bean name="myAdvice" class="com.little.adivce.MyAdivce" />

    <!-- 配置将增强织入目标对象 -->
    <aop:config>
        <!--
           com.itqf.spring.service.UserServiceImpl
           1 2 3 4
           1: 修饰符  public/private/*  可忽略
           2: 返回值  String/../*
           3: 全限定类名  类名  ..代表不限层数  *ServiceImpl
           4: (..)
          -->
        <aop:pointcut id="pc" expression="execution(* com.little.service.impl.*ServiceImpl.*(..))" />
        <aop:aspect ref="myAdvice">
            <aop:before method="before" pointcut-ref="pc" />
            <aop:after-returning method="afterReturning" pointcut-ref="pc" />
            <aop:around method="around" pointcut-ref="pc" />
            <aop:after-throwing method="afterException" pointcut-ref="pc" />
            <aop:after method="after" pointcut-ref="pc" />
        </aop:aspect>
    </aop:config>
</beans>

测试:

package com.little.springAOPTest;

import com.little.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringAOPTest {

        @Test
        public void test1() {
            // TODO 测试切面引入
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-aop.xml");
            UserService userServiceImpl = context.getBean("userService", UserService.class);
            userServiceImpl.addUser(null);
            userServiceImpl.deleteUser(11);
        }

}

二、基于注解

创建配置文件:applicationContext-aop-annotation.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans" 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-4.2.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.2.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">

    <bean name="userService" class="com.little.service.impl.UserServiceImpl" />

    <!--配置通知对象 -->
    <bean name="myAdvice" class="com.little.adivce.MyAdivce1" />

    <!-- 配置将增强织入目标对象 使用注解的方式 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

创建通知MyAdivce1:

package com.little.adivce;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
@Aspect
public class MyAdivce1 {

    /**
     //前置通知:目标方法运行之前调用
     //后置通知(如果出现异常不会调用):在目标方法运行之后调用
     //环绕通知:在目标方法之前和之后都调用
     //异常拦截通知:如果出现异常,就会调用
     //后置通知(无论是否出现 异常都会调用):在目标方法运行之后调用
     */
    @Pointcut("execution(* com.little.service.impl.*ServiceImpl.*(..))")
    public void pc() {

    }

    // 前置通知
    @Before("MyAdivce1.pc()")
    public void before() {
        System.out.println("这是前置通知");
    }

    // 后置通知
    @AfterReturning("execution(* com..*ServiceImpl.*(..))")
    public void afterReturning() {
        System.out.println("这是后置通知(方法不出现异常)");
    }

    @Around("execution(* com..*ServiceImpl.*(..))")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("这是环绕通知之前部分!!");
        Object object = point.proceed(); // 调用目标方法
        System.out.println("这是环绕通知之后的部分!!");
        return object;
    }

    @AfterThrowing("execution(* com..*ServiceImpl.*(..))")
    public void afterException() {
        System.out.println("异常通知!");
    }

    @After("execution(* com..*ServiceImpl.*(..))")
    public void after() {
        System.out.println("这也是后置通知,就算方法发生异常也会调用!");
    }

}


测试:

@Test
    public void test2() {
        // TODO 测试切面引入
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-aop-annotation.xml");
        UserService userServiceImpl = context.getBean("userService", UserService.class);
        userServiceImpl.addUser(null);
        userServiceImpl.deleteUser(11);
    }

Spring的学习(十二)——SpringAOP