AOP(2)-Spring实现AOP


利用Spring实现AOP

首先写一个UserService接口:

public interface UserService {
    public void add();
    public void delete();
    public void modify();
    public void query();
}

再写一个实现类:

public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("增加了数据");
    }

    @Override
    public void delete() {
        System.out.println("删除了数据");
    }

    @Override
    public void modify() {
        System.out.println("修改了数据");
    }

    @Override
    public void query() {
        System.out.println("查询了数据");
    }
}

然后在XML文件注册bean:

<bean id="userService" class="com.pro.UserServiceImpl"/>

好!

现在我们假设我们的工程就如上所示,现在需要你增加一个日志功能(就是在执行该方法前输出执行了什么方法)

那么Spring是如何实现的喃?

1、导入AOP依赖包

在XML文件中加入:

xmlns:aop="http://www.springframework.org/schema/aop"
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">

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

2、利用Spring-API接口实现:

2.1、前置方法:

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class BeforeLog implements MethodBeforeAdvice {

    //method 要执行的目标对象的方法
    //args 参数
    //target 目标对象
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
    }
}

2.2、后置方法:

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class AfterLog implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行了"+method.getName()+" 返回了"+returnValue);
    }
}

2.3、在bean注册:

    <bean id="beforeLog" class="com.log.BeforeLog"/>
    <bean id="afterLog" class="com.log.AfterLog"/>


<!--    方法一:使用原生spring api接口-->
<!--    配置aop-->
    <aop:config>
<!--        首先需要一个切入点 expression :表达式 execution 要执行的位置-->
        <aop:pointcut id="pointcut" expression="execution(* UserServiceImpl.*(..))"/>
<!--    执行环绕增加-->
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/>
    </aop:config>

现在万事大吉,进行测试:

@Test
   public void test(){
       ApplicationContext context = new ClassPathXmlApplicationConetext("applicationContext.xml");
       userService userService = context.getBean("userService");
       userService.add();
   }

3、利用自定义类实现:

先整一个自定义切入点:

public class DiyPoint {
    public void before()
    {
        System.out.println("=======方法执行前======");
    }
    public void after(){
        System.out.println("=======方法执行后======");
    }
}

同样地,再配置XML文件即可:

    第二种方式 :自定义类
    <bean id="diy" class="com.Diy.DiyPoint"/>
    <aop:config>
<!--        自定义切面  ref为要引用的类-->
        <aop:aspect ref="diy">
<!--            引入点-->
            <aop:pointcut id="point" expression="execution(* UserServiceImpl.*(..))"/>
<!--            通知-->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>

4、利用注解实现:

利用注解首先需要开启注解支持:

<!--    利用注解的方式-->
    <bean id="PointcutAnnotation" class="com.Diy.PointcutAnnotation"/>

接下来在com.Diy.PointcutAnnotation路径写我们的PointCutAnnotation类:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect//标注这个类是一个切面
public class PointcutAnnotation {

    //传入的参数代表切入的点
    @Before("execution(* com.kuang.pro.UserServiceImpl.*(..))")
    public void before()
    {
        System.out.println("======方法执行前=====");
    }

    @After("execution(* com.kuang.pro.UserServiceImpl.*(..))")
    public void after()
    {
        System.out.println("======方法执行后=====");
    }

    @Around("execution(* com.kuang.pro.UserServiceImpl.*(..))")
    public  void around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕前");

        joinPoint.proceed();

        System.out.println("环绕后");
    }
}

同样测试可以通过!!!O(∩_∩)O哈哈~

测试

美哉,下面开学SpringMVC!


文章作者: fatzard
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 fatzard !
评论
  目录
本站总访问量