Spring1.5——AspectJ基于xml和注解的演示

JAVA框架学习文章点这里
AspectJ:
AspectJ是一个基于Java语言的AOP框架
Spring2.0以后新增了对AspectJ切点表达式支持
@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
新版本Spring框架,建议使用AspectJ方式来开发AOP
主要用途:自定义开发
切入点表达式:
1.execution:用于描述方法
2.within:匹配包或子包中的方法
3.this:匹配实现接口的代理对象中的方法
4.target:匹配实现接口的目标对象中的方法
5.args:匹配参数格式符合标准的方法
6.bean(id) 对指定的bean所有的方法
主要使用的还是execution,以下举一个例子
execution(* com.h_Aspectj_xml.BookServiceImpl.*(..))
表示指定 返回值任意类型,在指定类中的任意方法(方法参数为任意类型)
AspectJ通知类型:
before:前置通知(应用:各种校验),在方法执行前执行,如果通知抛出异常,阻止方法运行
afterReturning:后置通知(应用:常规数据处理),方法正常返回后执行,如果方法中抛出异常,通知无法执行,必须在方法执行后才执行,所以可以获得方法的返回值。
around:环绕通知(应用:可以做任何事情),方法执行前后分别执行,可以阻止方法的执行,必须手动执行目标方法
afterThrowing:抛出异常通知(应用:包装异常信息),方法抛出异常后执行,如果方法没有抛出异常,无法执行,after:最终通知(应用:清理现场),方法执行完毕后执行,无论方法中是否出现异常
基于xml的使用:
before(前置方法)的使用:
目标类:

public interface BookService {
    public void addBook();
    public void deleteBook();
    public void selectBook();
}
package com.h_Aspectj_xml;

public class BookServiceImpl implements BookService{
    public void addBook() {
        System.out.println("add books");
    }
    public void deleteBook() {
        System.out.println("delete books");
    }
    public void selectBook() {
        System.out.println("select books");
    }
}

切面类:

package com.h_Aspectj_xml;

import org.aspectj.lang.JoinPoint;

public class MyAspect{
    public void myBefore(JoinPoint joinPoint) {
        System.out.println("before:"+joinPoint.getSignature().getName());
    }
}

配置文件:

<?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
                           ">
    <bean name="BookService" class="com.h_Aspectj_xml.BookServiceImpl"></bean>
    <bean name="MyAspect" class="com.h_Aspectj_xml.MyAspect"></bean>
    <aop:config>
        <!--配置切入点类-->
        <aop:pointcut expression="execution(* com.h_Aspectj_xml.BookServiceImpl.*(..))" id="myCutPoint"/>
        <!--配置切面,以及before使用的方法和切入点-->
        <aop:aspect ref="MyAspect">
            <aop:before method="myBefore" pointcut-ref="myCutPoint" />
        </aop:aspect>
    </aop:config>
</beans>

测试类:

package com.h_Aspectj_xml;

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

public class TestDemo {
    @Test
    public void test1() {
        String xmlPath = "com/h_Aspectj_xml/beans.xml";
        ApplicationContext appcont = new ClassPathXmlApplicationContext(xmlPath);
        BookService bookService = (BookService) appcont.getBean("BookService");
        bookService.addBook();
        bookService.selectBook();
        bookService.deleteBook();
    }
}

结果:

before:addBook
add books
before:selectBook
select books
before:deleteBook
delete books

after(后置方法)的使用:
目标类:同上
切面类:在上面的基础上加上一个方法

    public void myAfterReturning(JoinPoint joinPoint, Object ret) {
        System.out.println(joinPoint.getSignature().getName()+",after,返回值:"+ret);
    }

配置文件

    <aop:config>
        <aop:pointcut expression="execution(* com.h_Aspectj_xml.BookServiceImpl.*(..))" id="myCutPoint"/>
        <aop:aspect ref="MyAspect">
            <!--配置后置方法的方法名,切入点和返回值名-->
            <aop:after-returning method="myAfterReturning" pointcut-ref="myCutPoint" returning="ret"/>
        </aop:aspect>
    </aop:config>

结果:

add books
addBook,after,返回值:null
select books
selectBook,after,返回值:null
delete books
deleteBook,after,返回值:null

afterThrowing(异常处理)的使用
在前面的实现类中修改方法制造异常

    public void deleteBook() {
        int a = 10/0;
        System.out.println("delete books");
    }

在前面切面类的基础上添加方法:

    public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println(joinPoint.getSignature().getName()+"方法抛出异常:"+e.getMessage());
    }

修改配置文件:

    <aop:config>
        <aop:pointcut expression="execution(* com.h_Aspectj_xml.BookServiceImpl.*(..))" id="myCutPoint"/>
        <aop:aspect ref="MyAspect">
            <!--指定异常处理方法名,切入点和抛出的异常对象名称-->
            <aop:after-throwing method="myAfterThrowing" pointcut-ref="myCutPoint" throwing="e"/>
        </aop:aspect>
    </aop:config>

结果:

add books
select books
deleteBook方法抛出异常:/ by zero

around(环绕通知)的使用:
屏蔽掉之前在实现类中写的异常
在切面类中添加方法:

    public void myAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("前");
        //环绕需要手动调用目标方法
        Object object = joinPoint.proceed();
        System.out.println("后");
    }

修改配置文件

    <aop:config>
        <aop:pointcut expression="execution(* com.h_Aspectj_xml.BookServiceImpl.*(..))" id="myCutPoint"/>
        <aop:aspect ref="MyAspect">
            <aop:around method="myAround" pointcut-ref="myCutPoint"/>
        </aop:aspect>
    </aop:config>

运行结果:

前
add books
后
前
select books
后
前
delete books
后

after(最终)的使用:
在切面类中添加方法:

    public void myAfter(JoinPoint joinPoint) {
        System.out.println("finall");
    }

修改配置文件:

    <aop:config>
        <aop:pointcut expression="execution(* com.h_Aspectj_xml.BookServiceImpl.*(..))" id="myCutPoint"/>
        <aop:aspect ref="MyAspect">
            <aop:after method="myAfter" pointcut-ref="myCutPoint"/>
        </aop:aspect>
    </aop:config>

运行结果:

add books
finall
select books
finall
delete books
finall

注解的使用:
目标类:

package com.h_Aspectj_anno;

import org.springframework.stereotype.Service;

@Service("BookService")
public class BookServiceImpl implements BookService{
    public void addBook() {
        System.out.println("add books");
    }
    public void deleteBook() {
        //int a = 10/0;
        System.out.println("delete books");
    }
    public void selectBook() {
        System.out.println("select books");
    }
}

切面类:

package com.h_Aspectj_anno;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
//配置切面类
@Component//相当于xml中配置bean
@Aspect
public class MyAspect{
    //配置公共切入点,配置后可以方便后续方法引用
    @Pointcut("execution(* com.h_Aspectj_anno.BookServiceImpl.*(..))")
    public void myPointCut() {
    }
    //@Before("myPointCut()")
    public void myBefore(JoinPoint joinPoint) {
        System.out.println("before:"+joinPoint.getSignature().getName());
    }
    //@AfterReturning(value="myPointCut()" , returning="ret")
    public void myAfterReturning(JoinPoint joinPoint, Object ret) {
        System.out.println(joinPoint.getSignature().getName()+",after,返回值:"+ret);
    }
    //@AfterThrowing(value="myPointCut()", throwing="e")
    public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
        System.out.println(joinPoint.getSignature().getName()+"方法抛出异常:"+e.getMessage());
    }
    //@Around("myPointCut()")
    public void myAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("前");
        //环绕需要手动调用目标方法
        Object object = joinPoint.proceed();
        System.out.println("后");
    }
    //@After("myPointCut()")
    public void myAfter(JoinPoint joinPoint) {
        System.out.println("finall");
    }
}

配置文件:

<?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.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
                           ">
    <!-- 配置自动扫描 -->
    <context:component-scan base-package="com.h_Aspectj_anno"></context:component-scan>
    <!-- 配置注解自动代理 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

需要类:

package com.h_Aspectj_anno;

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

public class TestDemo {
    @Test
    public void test1() {
        String xmlPath = "com/h_Aspectj_anno/beans.xml";
        ApplicationContext appcont = new ClassPathXmlApplicationContext(xmlPath);
        BookService bookService = (BookService) appcont.getBean("BookService");
        bookService.addBook();
        bookService.selectBook();
        bookService.deleteBook();
    }
}

需要测试那个方法就打开注解,最终效果和使用xml的时候一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值