更多Spring开发在框架开发
1 AOP?
aop是独立于spring的框架,或者说是一个思想,并不是spring所特有的东西。aop是面向切面的变成框架或思想,是指项目的扩展功能不建议在原功能的实现源码上进行修改,而是额外的独立编写方法进行添加扩展功能。
关于aop的几个操作术语:
- Joinpoint,连接点: 类里面可以被增强扩展的所有方法
- Pointcut,切入点: 类里面具体要实施增强扩展的那些方法
- Advice,通知/增强:增强的逻辑,即扩展功能成为增强,分为前置增强,后置增强,环绕增强等。
Spring是使用aspectj来实现aop的这种思想,aspectj是独立于spring的一种技术,通常和spring一起使用进行aop的操作,是一个基于java的aop框架。使用aspectj实现aop也有xml配置方式和注解的方式。
2 AOP案例
案例目标: Dog类中对某些方法(切入点)进行增强,包含前置增强,后置增强和环绕增强。
项目环境:导入jar包,导入spring基本jar包,日志包,aop相关jar包
2.1 配置文件方法(常用)
Dog
package edu.kmust.entity;
/**
* 被增强类(即,需要增强的类)
* @author zhaoyuqiang
*
*/
public class Dog {
public void eat() {
System.out.println("狗狗黄思在吃饭....");
}
}
MyDog
package edu.kmust.entity;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 增强类(即,具体的增强类)
* @author zhaoyuqiang
*
*/
public class MyDog {
/**
* 前置增强,在被增强方法执行之前执行
*/
public void beforeEat() {
System.out.println("吃饭之前先叫两声.........");
}
/**
* 后置增强,在被增强方法执行之后执行
*/
public void afterEat() {
System.out.println("吃饭之后摇尾巴......");
}
/**
* 环绕增强,在被增强方法执行之前执行和执行之后都执行
* @param proceedingJoinPoint
* @throws Throwable
*/
public void arountEat(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//前置增强
System.out.println("吃饭之前先叫两声.........");
//执行被增强的方法
proceedingJoinPoint.proceed();
//后置增强
System.out.println("吃饭之后摇尾巴......");
}
}
配置文件,名字建议applicationContext.xml,位置建议src下
<?xml version="1.0" encoding="UTF-8"?>
<!-- 导入AOP约束,因为要用到IOC,所以也导入beans约束,该约束在
spring-framework-4.2.4.RELEASE-dist/spring-framework-4.2.4.RELEASE/docs/spring-framework-reference/html目录
下的xsd-configuration.html里面有
-->
<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 definitions here -->
<!--配置对象 -->
<bean id="dog" class="edu.kmust.entity.Dog"></bean>
<bean id="myDog" class="edu.kmust.entity.MyDog"></bean>
<!-- 1.配置AOP操作 -->
<aop:config>
<!--1.1 配置切入点
expression : 表达式
execution(* edu.kmust.entity.Dog.eat(..)) ,被增强的方法是Dog类里面的eat方法
execution(* edu.kmust.entity.Dog.*(..)) ,被增强的方法是Dog类里面的所有方法
execution(* *.*(..)) ,被增强的方法是所有类里面的所有方法
execution(* eat*(..)) ,被增强的方法是所有类里面的所有eat开头的方法
-->
<aop:pointcut expression="execution(* edu.kmust.entity.Dog.eat(..))" id="point_eat"/>
<!-- 1.2 配置切面
将增强用在切入点上
ref : 在增强的配置对象
-->
<aop:aspect ref="myDog">
<!-- 1.2.1 配置增强类型
aop:before : 前置增强
aop:after-returning :后置增强
aop:around : 环绕增强
pointcut-ref : 要增强的切入点id,(即aop:pointcut中的id值)
-->
<!-- <aop:before method="beforeEat" pointcut-ref="point_eat"/> -->
<aop:after-returning method="afterEat" pointcut-ref="point_eat"/>
<!-- <aop:around method="arountEat" pointcut-ref="point_eat"/> -->
</aop:aspect>
</aop:config>
</beans>
测试类
package edu.kmust.test;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import edu.kmust.entity.Dog;
/**
* 测试类
* @author zhaoyuqiang
*
*/
public class DogTest {
/**
* 测试
*/
@Test
public void test01() {
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
Dog dog = (Dog) context.getBean("dog");
dog.eat();
}
}
2.2 注解方法
增强类MyDog
package edu.kmust.entity;
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;
/**
* 增强类(即,具体的增强类)
* @author zhaoyuqiang
*
*/
@Aspect
public class MyDog {
/**
* 前置增强,在被增强方法执行之前执行
*/
@Before(value="execution(* edu.kmust.entity.Dog.eat(..))")
public void beforeEat() {
System.out.println("吃饭之前先叫两声.........");
}
/**
* 后置增强,在被增强方法执行之后执行
*/
@After(value="execution(* edu.kmust.entity.Dog.eat(..))")
public void afterEat() {
System.out.println("吃饭之后摇尾巴......");
}
/**
* 环绕增强,在被增强方法执行之前执行和执行之后都执行
* @param proceedingJoinPoint
* @throws Throwable
*/
@Around(value="execution(* edu.kmust.entity.Dog.eat(..))")
public void arountEat(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
//前置增强
System.out.println("吃饭之前先叫两声.........");
//执行被增强的方法
proceedingJoinPoint.proceed();
//后置增强
System.out.println("吃饭之后摇尾巴......");
}
}
applicationContext.xml配置文件
<!--配置对象 -->
<bean id="dog" class="edu.kmust.entity.Dog"></bean>
<bean id="myDog" class="edu.kmust.entity.MyDog"></bean>
<!-- 2.配置AOP操作,注解方式 -->
<!-- 2.1 开启AOP操作 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>