AOP使用场景:
可以看出上图场景导致代码冗余度特别高,这个问题我们可以采取两种办法来解决:
一,将复用代码抽取成一个方法,在需要的位置手动调用此方法
二,运用AOP思想,不需要在业务方法中手动调用抽取的方法,通过配置自动执行
方法一:
普通解决方案,比较简单,这里不再详细叙述。下面进入方法二------本篇文章的核心阶段。
方法二:
学习AOP思想之前,必须先掌握几个概念:
1.通知/增强(Advice):用来增强的代码。(类比上述的相同代码)
2.切入点(Pointcut):目标对象中,需要织入或者已经织入的方法。(类比上述调用aMethod()的位置)
3.织入(Weaving):是一个过程,将通知应用到指定方法形成目标对象的过程。
4.目标对象:被代理对象
5.代理对象:将通知织入到目标对象中,形成代理对象。
图解:
将相同代码根据业务需求确定通知类型定义到通知类中。
案例:
一,通知类
我们采用注解的方式定义 ,不需要再在配置文件中配置,只需要在配置中配置开启注解即可,相对简单!
//通过此注解定义通知类
@Aspect
public class MyAdvice {
//@Before代表前置通知,并设置切入点
@Before("execution(* cn.zua.aop.method.*.*(..))")
public void aMethod(){
System.out.println("这是前置通知!");
}
}
这里只定义了前置通知。execution(* cn.zua.aop.method.*.*(..):标识 cn.zua.aop.method包下的所有方法都作为切点,执行此通知
二,目标对象
package cn.zua.aop.method;
public class MyMethod {
public void insert(){
System.out.println("测试方法1");
}
public void delete(){
System.out.println("测试方法2");
}
public void update(){
System.out.println("测试方法3");
}
}
定义的这三个方法都在cn.zua.aop.method包下,符合前置通知切点的条件,所以执行这些方法时,一定会先执行通知!
三,配置
在applicationContext.xml配置通知类,交给spring IOC容器管理
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
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-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">
<!-- 启用对注解的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 将通知类注入到spring IOC容器 -->
<bean class="cn.zua.aop.test.MyAdvice"></bean>
<bean id="myMethod" class="cn.zua.aop.method.MyMethod"></bean>
</beans>
四,测试
public class TestAop {
@Test
public void testAop() throws Exception {
ApplicationContext context=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
MyMethod myMethod =(MyMethod) context.getBean("myMethod");
//调用MyMethod的方法,结果显示,在执行insert()之前,先只执行了前置通知 aMethod()
myMethod.insert();
}
五,结果
第一次用这么长时间写一篇博客,这是自己昨天再次看书的时候,感觉突然对AOP又有了新的理解,如有不准确之处,欢迎指出!