spring基于注解声明的Aspectj

基于注解式声明Aspectj实例分析

AOP描述

与基于代理类的AOP时限相比。基于xml的声明式Aspectj要便捷的多,但是它也存在这一些缺点,那就是要在spring文件中配置大量的代码信息。为了解决这个问题,Aspectj框架为AOP的实现提供了一套注解,用以取代spring配置文件中为实现AOP功能所配置的臃肿代码。

Aspectj的注解介绍及描述

spring基于注解声明的Aspectjspring基于注解声明的Aspectj

案例分析

用idea创建一个maven模块,项目结构如下:

spring基于注解声明的Aspectj

编写要通知的对象

在java目录下创建包,首先创建接口UserDao

package com.chen.jdk;

public interface UserDao {
    public void addUser();
    public void deleteUser();
}

接在在impl目录中创建接口的实现类UserDaoImpl

package com.chen.jdk.impl;

import com.chen.jdk.UserDao;
import org.springframework.stereotype.Repository;

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void addUser() {
        System.out.println("添加用户");
    }

    @Override
    public void deleteUser() {
        System.out.println("删除用户");
    }
}

@Repository注解

spring中的注解,@Repository用于标注数据访问组件,即DAO组件。例:

@Repository
public class VentorDaoImpl implements iVentorDao {
}

在一个稍大的项目中,如果组件采用xml的bean定义来配置,显然会增加配置文件的体积,查找以及维护起来也不太方便。

Spring2.5为我们引入了组件自动扫描机制,他在类路径下寻找标注了上述注解的类,并把这些类纳入进spring容器中管理

它的作用和在xml文件中使用bean节点配置组件时一样的。要使用自动扫描机制。

也就是说,它所注解的类会交由spring容器管理,就像我们把对象交由spring管理一样。在spring中对象就是那些配置文件中的bean。

applicationContext配置文件中配置了UserDao实现类的bean就不用这个注解了。

编写切面通知类

package com.chen.aspectj.annotation;

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

/**
 * 切面类,用来编写通知
 */
@Aspect
@Component
public class MyAspect {
    //定义切入点表达式
    @Pointcut("execution(* com.chen.jdk.*.*(..))")
    //使用一个返回值为void、方法体为空的方法来命名切入点
    private void myPointCut(){}
    //前置通知
    @Before("myPointCut()")
    public void myBefore(JoinPoint joinPoint){
        System.out.println("前置通知:模拟执行权限检查....");
        System.out.println("目标类是:"+joinPoint.getTarget());
        System.out.println(",被植入增强处理的目标方法为:"+joinPoint.getSignature().getName());
    }
    //后置通知
    @AfterReturning("myPointCut()")
    public void myAfterReturning(JoinPoint joinPoint){
        System.out.println("后置通知:模拟日志记录...");
        System.out.println(",被植入增强处理的目标方法为:"+joinPoint.getSignature().getName());
    }
}

切入点表达式,是指的是在这个路径下的任何目录任何方法都会被通知,这里有前置通知和后置通知

编写配置

在recourses下面创建applicationContext.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"
       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.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
    <!--把对象UserDao和的创建交由spring管理-->
    <bean id="userDao" class="com.chen.jdk.impl.UserDaoImpl"/>
    <bean id="myAspect" class="com.chen.aspectj.annotation.MyAspect"/>
    <!--指定要扫描的包,让注解生效-->
    <context:component-scan base-package="com.chen"/>
    <!--启动基于注解声明式Aspectj支持-->
    <aop:aspectj-autoproxy/>
</beans>

把配置文件交给idea来管理

spring基于注解声明的Aspectj

编写测试类

创建测试类

package com.chen.aspectj.annotation;

import com.chen.jdk.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAnnotationAspectj {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //1 从容器中获得内容
        UserDao userDao = (UserDao) applicationContext.getBean("userDao");
        //2 执行方法
        userDao.deleteUser();
    }
}

测试结果

spring基于注解声明的Aspectj

案例总结

案例中对UserDao的删除用户的方法进行前后通知。

spring中的bean可以帮我们管理对象,使用注解方式来实现aop的切面通知比jdk动态代理或者cglib代理或者xml方式实现通知要便捷得多。
首先有要通知的对象,然后有要通知的内容,即有切面类。
具体就是要通知那些方法,通知方式:前置通知还是后置通知,还是异常通知等等…
最后就是配置文件要添加,指定要扫描的包并且启动对于aspectj注解的支持。

上一篇:AspectJ的介绍和使用方法


下一篇:AOP面向切面编程:AspectJ:注解开发