一:aop概念,原理,操作术语
概念: 面向切面编程,采取横线抽取机制,取代传统纵向继承体系重复性代码。
操作术语:
增强/通知:增强的逻辑,例如:日志扩展功能
连接点:类里面那些方法可以被增强,这些方法称为连接点。
切入点:类里面很多方法可以被增强,实际增强的方法称为切入点。
切面:将增强用到切入点的过程。
增强类型:
前置增强 :在方法之前执行
后置增强 :在方法之后执行
环绕增强 :在方法之前和之后执行
最终增强 :在后置之后执行
异常增强 :方法出现异常执行
常用表达式:
execution(访问修饰符 全类名.方法名(参数)) * 通配符
(1) execution(* 全类名.方法名(..)) 指定类某个方法增强
(2) execution(* 全类名.*(..)) 指定类所有方法增强
(3) execution(* *.*(..)) 指定所有类所有方法增强
依赖jar:
二:基于aspectj的两种操作方式
1:基于aspectj的xml配置
被增强类:
public class Book {
private final static Logger logger = LoggerFactory.getLogger(Book.class);
public void buy(){
logger.info("...........购买书本.........");
}
}
增强类:
/**
* @version 1.0
* @auther gaoming
* @create 2018/7/16
* 增强类
*/
public class BookOrder {
private final static Logger logger = LoggerFactory.getLogger(Book.class);
public void order(){
logger.info("[前置增强]....预定书本....");
}
public void takeBill(){
logger.info("[后置增强]...拿发票....");
}
public void leave(){
logger.info("[最终增强]...离开书店....");
}
/*
*环绕增强方法
**/
public void around(ProceedingJoinPoint proceed) throws Throwable {
//方法之前执行的逻辑
logger.info("[环绕增强]方法之前...");
//被执行增强的方法
proceed.proceed();
//方法之后执行的逻辑
logger.info("[环绕增强]方法之后...");
}
}
aop-config.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:utile="http://www.springframework.org/schema/util"
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-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!--1 配置对象-->
<bean id="book" class="com.ustc.aop.Book"></bean>
<bean id="bookOrder" class="com.ustc.aop.BookOrder"></bean>
<!--2 配置aop操作-->
<aop:config>
<!--2.1 配置切入点-->
<aop:pointcut id="book_pointcut" expression="execution(* com.ustc.aop.Book.buy(..))"></aop:pointcut>
<!--2.2 配置切入面:把增强用到方法上面-->
<aop:aspect ref="bookOrder"> <!--指定增强类-->
<!--配置增强类型:method 指定增强类使用的方法 pointcut-ref:指定增强应用到那个切入点-->
<!-- 前置增强-->
<aop:before method="order" pointcut-ref="book_pointcut"></aop:before>
<!-- 后置增强-->
<aop:after method="takeBill" pointcut-ref="book_pointcut"></aop:after>
<!--最终增强-->
<aop:after-returning method="leave" pointcut-ref="book_pointcut"></aop:after-returning>
<!--环绕增强-->
<aop:around method="around" pointcut-ref="book_pointcut"></aop:around>
</aop:aspect>
</aop:config>
</beans>
测试类:
/**
* Created by gaoming on 2018/7/16.
* 测试类
*/
public class BookTest {
@Test(enabled = true)
public void testBuy() throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("aop-config.xml");
Book book = (Book) context.getBean("book");
book.buy();
}
}
输出结果:
2:基于aspectj的注解方式
被增强类
/**
* @version 1.0
* @auther gaoming
* @create 2018/7/16
*/
public class Book {
private final static Logger logger = LoggerFactory.getLogger(Book.class);
public void buy(){
logger.info("...........购买书本.........");
}
}
增强类
package com.ustc.aop;/**
* Created by gaoming on 2018/7/16.
*/
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @version 1.0
* @auther gaoming
* @create 2018/7/16
* 增强类
*/
@Aspect
public class BookOrder {
private final static Logger logger = LoggerFactory.getLogger(Book.class);
@Before(value = "execution(* com.ustc.aop.Book.buy(..))")
public void order(){
logger.info("[前置增强]....预定书本....");
}
@After(value = "execution(* com.ustc.aop.Book.buy(..))")
public void takeBill(){
logger.info("[后置增强]...拿发票....");
}
@AfterReturning(value = "execution(* com.ustc.aop.Book.buy(..))")
public void leave(){
logger.info("[最终增强]...离开书店....");
}
/*
*环绕增强方法
**/
@Around(value = "execution(* com.ustc.aop.Book.buy(..))")
public void around(ProceedingJoinPoint proceed) throws Throwable {
//方法之前执行的逻辑
logger.info("[环绕增强]方法之前...");
//被执行增强的方法
proceed.proceed();
//方法之后执行的逻辑
logger.info("[环绕增强]方法之后...");
}
}
aop-config.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:utile="http://www.springframework.org/schema/util"
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-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!--开启aop操作-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--1 配置对象-->
<bean id="book" class="com.ustc.aop.Book"></bean>
<bean id="bookOrder" class="com.ustc.aop.BookOrder"></bean>
</beans>
测试类:
package com.ustc.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.Test;
/**
* Created by gaoming on 2018/7/16.
* 测试类
*/
public class BookTest {
@Test(enabled = true)
public void testBuy() throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("aop-config.xml");
Book book = (Book) context.getBean("book");
book.buy();
}
}
输出结果:
[2018-07-16 21:08:33,538][INFO][main][1225][com.ustc.aop.Book][com.ustc.aop.BookOrder.around(BookOrder.java:41)]
[环绕增强]方法之前...
[2018-07-16 21:08:33,539][INFO][main][1226][com.ustc.aop.Book][com.ustc.aop.BookOrder.order(BookOrder.java:22)]
[前置增强]....预定书本....
[2018-07-16 21:08:33,740][INFO][main][1427][com.ustc.aop.Book][com.ustc.aop.Book.buy(Book.java:17)]
...........购买书本.........
[2018-07-16 21:08:33,740][INFO][main][1427][com.ustc.aop.Book][com.ustc.aop.BookOrder.around(BookOrder.java:45)]
[环绕增强]方法之后...
[2018-07-16 21:08:33,741][INFO][main][1428][com.ustc.aop.Book][com.ustc.aop.BookOrder.takeBill(BookOrder.java:27)]
[后置增强]...拿发票....
[2018-07-16 21:08:33,746][INFO][main][1433][com.ustc.aop.Book][com.ustc.aop.BookOrder.leave(BookOrder.java:32)]
[最终增强]...离开书店....