Spring核心之面向切面编程(AOP)

  • 一、简介
  • 二、术语
  • 三、方式
  • 1. Spring AOP
  • 2. Spring Aspect AOP (XML)
  • 3. Spring Aspect AOP (Annotation)
  • 四、通知(Spring AOP方式)
  • 1. MethodBeforeAdvice(前置通知)
  • 2. AfterReturningAdvice(后置通知)
  • 3. MethodInterceptor(环绕通知)
  • 4. ThrowsAdvice(异常通知)
  • 5. IntroductionInterceptor(引介通知)
  • 五、通知(Spring Aspect AOP -XML)
  • 六、通知(Spring Aspect AOP -Annotation)


一、简介

  • AOP(Aspect Oriented Programming,面向切面编程)是软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP,可以对业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
  • AOP主要应用在事务处理、日志管理、权限控制、异常处理等方面。

二、术语

名称

解释

Aspect(切面)

是对象操作过程中的截面,实际上切面是一段程序代码,这段代码将被植入到程序的流程中。

Proxy(代理)

是将通知应用当目标对象后创建的对象。

Joinpoint(连接点)

应用程序执行过程中插入切面的点,是对象操作过程中的某个阶段点。

Pointcut(切入点)

是连接点的集合切面与程序流的交叉点,及程序的切入点,确切地说它是切面注入到程序中的位置。

Advice(通知)

是在切面的某个特定的连接点上执行的动作。通知有多种类型。

Target Object(目标对象)

是被通知的对象,既可以是编写的类,也可以是需要添加指定行为的第三方类。

Weaving(织入)

把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象的过程

Introduction(引入)

引入允许我们向现有的类添加新的方法和属性

三、方式

1. Spring AOP

  • 需要导入的jar包

2. Spring Aspect AOP (XML)

  • 需要导入的jar包

3. Spring Aspect AOP (Annotation)

  • 需要导入的jar包

四、通知(Spring AOP方式)

1. MethodBeforeAdvice(前置通知)

  • 在方法之前自动执行的通知称为前置通知,可以应用于权限管理等功能。
  • 案例(使UserDao中的方法在执行前输出一些信息)

接口

package com.aop;

public interface UserDao {
    int userLogin(String username,String password);
}

实现类

package com.aop;

public class UserDaoImpl implements UserDao {

    @Override
    public int userLogin(String username, String password) {
        System.out.println("---方法逻辑执行---");
        return 0;
    }
}

切面类

package com.aop;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class LogBeforeAspect implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {

        // 执行逻辑之前输出的内容

        System.out.println("---前置通知开始---");
        // method表示通知的方法名称
        System.out.println(method);
        // objects表示通知的方法的各个参数
        System.out.println(objects.length);
        // o表示通知的方法的哈希值
        System.out.println(o);

        System.out.println("---前置通知结束---");


    }
}

配置文件

<?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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- target object -->
    <bean id="userDao" class="com.aop.UserDaoImpl"></bean>

    <!-- 切面 -->
    <bean id="logAspect" class="com.aop.LogAspect"></bean>
    <bean id="logBeforeAspect" class="com.aop.LogBeforeAspect"></bean>

    <!-- 代理 -->
    <bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口 -->
        <property name="proxyInterfaces" value="com.aop.UserDao"></property>
        <!-- 目标对象 -->
        <property name="target" ref="userDao"></property>
        <!-- 切面-->
        <property name="interceptorNames" value="logBeforeAspect"></property>
        <!-- 代理目标对象是否为类 使用JDK代理用的是接口-->
        <property name="proxyTargetClass" value="false"></property>

    </bean>
</beans>

测试类

package com.aop;

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

public class Test_AOP {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = context.getBean("userDaoProxy",UserDao.class);
        userDao.userLogin("test1","123");
    }
}

控制台输出内容

Java aop切面需要用到的依赖_aop

2. AfterReturningAdvice(后置通知)

  • 在方法之后自动执行的通知称为后置通知,可以应用于关闭流、上传文件、删除临时文件等功能。
  • 案例(使UserDao中的方法在执行后输出一些信息)

接口

package com.aop;

public interface UserDao {
    int userLogin(String username,String password);
}

实现类

package com.aop;

public class UserDaoImpl implements UserDao {

    @Override
    public int userLogin(String username, String password) {
        System.out.println("---方法逻辑执行---");
        return 0;
    }
}

切面类

package com.aop;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class LogAfterAspect implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {

        // 执行逻辑之后输出的内容

        System.out.println("---后置通知开始---");

        // o表示通知的方法的返回值,若没有返回值则o为null
        System.out.println(o);
        // method表示通知的方法名称
        System.out.println(method);
        // objects表示通知的方法中的各个参数
        System.out.println(objects.length);
        // o1表示通知的方法的哈希值
        System.out.println(o1);

        System.out.println("---后置通知结束---");
    }
}

配置文件

<?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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- target object -->
    <bean id="userDao" class="com.aop.UserDaoImpl"></bean>

    <!-- 切面 -->
    <bean id="logAspect" class="com.aop.LogAspect"></bean>
    <bean id="logBeforeAspect" class="com.aop.LogBeforeAspect"></bean>
    <bean id="LogAfterAspect" class="com.aop.LogAfterAspect"></bean>


    <!-- 代理 -->
    <bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口 -->
        <property name="proxyInterfaces" value="com.aop.UserDao"></property>
        <!-- 目标对象 -->
        <property name="target" ref="userDao"></property>
        <!-- 切面-->
        <property name="interceptorNames" value="LogAfterAspect"></property>
        <!-- 代理目标对象是否为类 使用JDK代理用的是接口-->
        <property name="proxyTargetClass" value="false"></property>

    </bean>
</beans>

测试类

package com.aop;

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

public class Test_AOP {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = context.getBean("userDaoProxy",UserDao.class);
        userDao.userLogin("test1","123");
    }
}

控制台输出内容

Java aop切面需要用到的依赖_Java aop切面需要用到的依赖_02

3. MethodInterceptor(环绕通知)

  • 在方法前后自动执行的通知称为焕然通知,可以应用于日志、事务管理等功能。
  • 案例(使UserDao中的方法在执行前后输出一些信息)

接口

package com.aop;
// 接口
public interface UserDao {
   int userLogin(String username,String password);
}

实现类

package com.aop;
// 实现类
public class UserDaoImpl implements UserDao {

    @Override
    public int userLogin(String username, String password) {
        System.out.println("---方法逻辑执行---");
        return 0;
    }
}

切面类

package com.aop;
// 切面类
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class LogAspect implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        // 1.执行逻辑之前输出的内容
        System.out.println("---环绕通知开始---");
        // 2.执行逻辑
        Object obj = methodInvocation.proceed();
        // 3.执行逻辑之后输出的内容
        System.out.println("---环绕通知结束---");
        return obj;
    }
}

配置文件

<?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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- target object -->
    <bean id="userDao" class="com.aop.UserDaoImpl"></bean>

    <!-- 切面 -->
    <bean id="logAspect" class="com.aop.LogAspect"></bean>

    <!-- 代理 -->
    <bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口 -->
        <property name="proxyInterfaces" value="com.aop.UserDao"></property>
        <!-- 目标对象 -->
        <property name="target" ref="userDao"></property>
        <!-- 切面-->
        <property name="interceptorNames" value="logAspect"></property>
        <!-- 代理目标对象是否为类 使用JDK代理用的是接口-->
        <property name="proxyTargetClass" value="false"></property>

    </bean>
</beans>

测试类

package com.aop;

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

public class Test_AOP {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = context.getBean("userDaoProxy",UserDao.class);
        userDao.userLogin("test1","123");
    }
}

控制台输出内容

Java aop切面需要用到的依赖_xml_03

4. ThrowsAdvice(异常通知)

  • 在方法抛出异常时自动执行的通知称为异常通知,可以应用于处理异常记录日志等功能。
  • 案例(在UserDao执行发生异常时输出一些内容)

接口

package com.aop;

public interface UserDao {
    int userLogin(String username,String password);
}

实现类

package com.aop;

public class UserDaoImpl implements UserDao {

    @Override
    public int userLogin(String username, String password) {
        System.out.println("---方法逻辑执行---");

        // 以下代码会产生一个异常
        String id = null;
        id.charAt(0);

        return 0;
    }
}
package com.aop;

import org.springframework.aop.ThrowsAdvice;

import java.lang.reflect.Method;

public class LogThrowsAspect implements ThrowsAdvice {

    public void afterThrowing(Method method,Object[] objects,Object o,Throwable error){

        //执行逻辑时发生异常所输出的内容

        System.out.println("---异常通知开始---");

        // method表示通知的方法名称
        System.out.println(method);
        // objects表示通知的方法中的各个参数
        System.out.println(objects.length);
        // o表示通知的方法的哈希值
        System.out.println(o);
        // error表示通知的方法的异常
        System.out.println(error);

        System.out.println("---异常通知结束---");
    }
}

配置文件

<?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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- target object -->
    <bean id="userDao" class="com.aop.UserDaoImpl"></bean>

    <!-- 切面 -->
    <bean id="logAspect" class="com.aop.LogAspect"></bean>
    <bean id="logBeforeAspect" class="com.aop.LogBeforeAspect"></bean>
    <bean id="logAfterAspect" class="com.aop.LogAfterAspect"></bean>
    <bean id="logThrowsAspect" class="com.aop.LogThrowsAspect"></bean>


    <!-- 代理 -->
    <bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口 -->
        <property name="proxyInterfaces" value="com.aop.UserDao"></property>
        <!-- 目标对象 -->
        <property name="target" ref="userDao"></property>
        <!-- 切面-->
        <property name="interceptorNames" value="logThrowsAspect"></property>
        <!-- 代理目标对象是否为类 使用JDK代理用的是接口-->
        <property name="proxyTargetClass" value="false"></property>

    </bean>
</beans>

测试类

package com.aop;

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

public class Test_AOP {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = context.getBean("userDaoProxy",UserDao.class);
        userDao.userLogin("test1","123");
    }
}

控制台输出内容

Java aop切面需要用到的依赖_spring_04

5. IntroductionInterceptor(引介通知)

  • 在目标中添加一些新的方法和属性,可以应用于修改旧版本程序(增强类)。
  • 案例(在UserDao接口中加入新的业务)

接口

package com.aop;

public interface EUserDao {
    int del(Integer id);
}

实现类

package com.aop;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.IntroductionInterceptor;

public class EUserDaoImpl implements EUserDao, IntroductionInterceptor {

    @Override
    public int del(Integer id) {
        System.out.println("---新的方法执行逻辑---");
        return 0;
    }

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        if (implementsInterface(methodInvocation.getMethod().getDeclaringClass())) {
            return methodInvocation.getMethod().invoke(this, methodInvocation.getArguments());
        } else {
            return methodInvocation.proceed();
        }
    }

    @Override
    public boolean implementsInterface(Class<?> aClass) {
        // 返回实现接口
        return aClass.isAssignableFrom(EUserDao.class);
    }
}

配置文件

<?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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- target object -->
    <bean id="userDao" class="com.aop.UserDaoImpl"></bean>
    <bean id="eUserDao" class="com.aop.EUserDaoImpl"></bean>

    <!-- 切面 -->
    <bean id="logAspect" class="com.aop.LogAspect"></bean>
    <bean id="logBeforeAspect" class="com.aop.LogBeforeAspect"></bean>
    <bean id="logAfterAspect" class="com.aop.LogAfterAspect"></bean>
    <bean id="logThrowsAspect" class="com.aop.LogThrowsAspect"></bean>
        <!-- 引介通知 -->
    <bean id="userDaoAspect" class="org.springframework.aop.support.DefaultIntroductionAdvisor">
        <constructor-arg ref="eUserDao"></constructor-arg>
        <constructor-arg value="com.aop.EUserDao"></constructor-arg>
    </bean>


    <!-- 代理 -->
    <bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 代理接口 -->
        <property name="proxyInterfaces" value="com.aop.UserDao"></property>
        <!-- 目标对象 -->
        <property name="target" ref="userDao"></property>
        <!-- 切面-->
        <property name="interceptorNames" value="userDaoAspect"></property>
        <!-- 代理目标对象是否为类 使用JDK代理用的是接口-->
        <property name="proxyTargetClass" value="false"></property>

    </bean>
</beans>

测试类

package com.aop;

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

public class Test_AOP {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        EUserDao eUserDao = context.getBean("userDaoProxy",EUserDao.class);
        eUserDao.del(1);
    }
}

控制台输出内容

Java aop切面需要用到的依赖_aop_05

五、通知(Spring Aspect AOP -XML)

  • 案例

接口

package com.aop;

public interface UserDao {
    int userLogin(String username,String password);
}

实现类

package com.aop;

public class UserDaoImpl implements UserDao{
    @Override
    public int userLogin(String username, String password) {
        System.out.println("---执行方法逻辑---");
        return 0;
    }
}

切面类

package com.aop;


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

public class LogAspect {

    // 前置通知
    public void myBefore(JoinPoint joinPoint){
        System.out.println("---前置通知开始---");
        System.out.println("---目标对象:"+ joinPoint.getTarget()+"---");
        System.out.println("---方法:"+joinPoint.getSignature().getName()+"---");
        System.out.println("---前置通知结束---");

    }

    // 后置通知
    public void myAfterReturning(JoinPoint joinPoint){
        System.out.println("---后置通知开始---");
        System.out.println("---目标对象:"+ joinPoint.getTarget()+"---");
        System.out.println("---方法:"+joinPoint.getSignature().getName()+"---");
        System.out.println("---后置通知结束---");
    }

    // 环绕通知
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("---环绕通知开始---");
        System.out.println("---目标对象:"+ proceedingJoinPoint.getTarget()+"---");
        System.out.println("---方法:"+proceedingJoinPoint.getSignature().getName()+"---");
        Object obj = proceedingJoinPoint.proceed();
        System.out.println("---环绕通知结束---");
        return obj;
    }

    // 异常通知
    public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
        System.out.println("---异常通知开始");
        System.out.println("异常:" + e.getMessage());
        System.out.println("---异常通知结束");
    }

    // 最终通知    Aspect中的最终通知是在执行完方法逻辑后执行,而Spring中的最终通知是在
    public void myAfter(JoinPoint joinPoint){
        System.out.println("---最终通知开始---");
        System.out.println("---目标对象:"+ joinPoint.getTarget()+"---");
        System.out.println("---方法:"+joinPoint.getSignature().getName()+"---");
        System.out.println("---最终通知结束---");
    }
}

测试类

package com.aop;

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

public class TestAop {
    @Test
    public void fun1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) context.getBean("userDao");
        userDao.userLogin("test","123");
    }
}

控制台输出内容

Java aop切面需要用到的依赖_Java aop切面需要用到的依赖_06

六、通知(Spring Aspect AOP -Annotation)

  • 案例

接口

package com.aop;

public interface UserDao {
    int userLogin(String username,String password);
}

实现类

package com.aop;

import org.springframework.stereotype.Repository;

@Repository("userDao")
public class UserDaoImpl implements UserDao{
    @Override
    public int userLogin(String username, String password) {
        System.out.println("---执行方法逻辑---");
        return 0;
    }
}

切面类

package com.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 切面类
 */
@Component  //组件注解
@Aspect     //切面类注解
public class LogAspect {

    // 切入点
    @Pointcut("execution(* com.aop.UserDao.userLogin(..))")
    public void myPointCut(){
    }

    // 前置通知
    @Before("myPointCut()")
    public void myBefore(JoinPoint joinPoint){
        System.out.println("---前置通知开始---");
        System.out.println("---目标对象:"+ joinPoint.getTarget()+"---");
        System.out.println("---方法:"+joinPoint.getSignature().getName()+"---");
        System.out.println("---前置通知结束---");

    }

    // 后置通知
    @AfterReturning("myPointCut()")
    public void myAfterReturning(JoinPoint joinPoint){
        System.out.println("---后置通知开始---");
        System.out.println("---目标对象:"+ joinPoint.getTarget()+"---");
        System.out.println("---方法:"+joinPoint.getSignature().getName()+"---");
        System.out.println("---后置通知结束---");
    }

    // 环绕通知
    @Around("myPointCut()")
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("---环绕通知开始---");
        System.out.println("---目标对象:"+ proceedingJoinPoint.getTarget()+"---");
        System.out.println("---方法:"+proceedingJoinPoint.getSignature().getName()+"---");
        Object obj = proceedingJoinPoint.proceed();
        System.out.println("---环绕通知结束---");
        return obj;
    }

    // 异常通知
    @AfterThrowing(value = "myPointCut()",throwing = "e")
    public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
        System.out.println("---异常通知开始");
        System.out.println("异常:" + e.getMessage());
        System.out.println("---异常通知结束");
    }

    // 最终通知    Aspect中的最终通知是在执行完方法逻辑后执行,而Spring中的最终通知是在
    @After("myPointCut()")
    public void myAfter(JoinPoint joinPoint){
        System.out.println("---最终通知开始---");
        System.out.println("---目标对象:"+ joinPoint.getTarget()+"---");
        System.out.println("---方法:"+joinPoint.getSignature().getName()+"---");
        System.out.println("---最终通知结束---");
    }
}

配置文件

<?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:tx="http://www.springframework.org/schema/tx"
       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/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 扫描com.aop包中所有的类 -->
    <context:component-scan base-package="com.aop"></context:component-scan>

    <!-- 开启切面的自动代理 -->
    <aop:aspectj-autoproxy/>

</beans>

测试类

package com.aop;

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

public class TestAop {

    @Test
    public void fun1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) context.getBean("userDao");
        userDao.userLogin("test","123");
    }
}

控制台输出内容

Java aop切面需要用到的依赖_aop_07