AspectJ的注解开发AOP
1.AspectJ简介
2.环境配置
<?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 definitions here --> <!--开启aspectJ的注解开发,自动代理==========--> <aop:aspectj-autoproxy/> </beans>
3.AspectJ通知类型
4.在通知中通过value属性定义切点
注意访问修饰符可有可无,..也是任意
5.入门案例(前置通知)
pom.xml文件中导入相应的依赖
编写目标类和切面类
目标类:ProductDao,老样子
切面类:@Aspect public class MyAspectAnno { @Before(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.save(..))") public void before() { System.out.println("前置通知"); } }
1.@Aspect:代表的是这个类是切面类2.@Before(里面添加execution函数定义要切入点)*
编写applicationContext文件
<!--开启aspectJ的注解开发,自动代理==========--> <aop:aspectj-autoproxy/> <!--定义目标类--> <bean id="productDao" class="com.imooc.aspectJ.demo1.ProductDao"/> <!--定义切面类--> <bean id="myAspectAnno" class="com.imooc.aspectJ.demo1.MyAspectAnno"/> </beans>
编写测试类
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringDemo1 { @Resource(name = "productDao") private ProductDao productDao; @Test public void demo1() { productDao.save(); productDao.delete(); productDao.findAll(); productDao.findOne(); productDao.update(); } }
也可以在增强的方法中传入JoinPoint获取切点信息(注意要导入org.aspectj.lang.JoinPoint的包)
@Before(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.save(..))") public void before(JoinPoint joinPoint) { System.out.println("前置通知" + joinPoint); }
6.其他通知的使用
- AfterReturn 通过return属性可以定义方法的返回值作为参数
@AfterReturning(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.save(..))") public void afterReturing(Object result){ System.out.println("后置通知=================="+result); }
-Around环绕通知
around方法的返回值就是目标代理方法执行返回值
参数为ProceedingJoinPoint可以调用拦截目标方法执行
@Around(value = "execution(* com.imooc.aspectJ.demo1.ProductDao.save(..))") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("环绕前通知================"); Object obj = joinPoint.proceed(); // 执行目标方法 System.out.println("环绕后通知================"); return obj; }
- AfterThrowing 异常抛出通知
- After 最终通知
@After(value=value = "execution(* com.imooc.aspectJ.demo1.ProductDao.findAll(..))") public void after(){ System.out.println("最终通知=================="); }
- 无论目标方法是否有异常 都会执行*
7.通过PointCut为切点命名
在增强类中,添加一个标签,Pointcut
@Pointcut(value="execution(* com.imooc.aspectJ.demo1.ProductDao.save(..))") private void myPointcut1(){}
AspectJ的XML方式开发AOP
入门案例
编写目标类和切面类(增强类)
目标类老生常谈了。切面类:不需要添加标签编写applicationContext的xml文件
<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="customDao" class="com.imooc.aspectJ.demo2.CustomDaoImpl"/> <!--定义切面类--> <bean id="myAspectXml" class="com.imooc.aspectJ.demo2.MyAspectXml"/> <!--aop的相关配置--> <aop:config> <!--配置切入点--> <aop:pointcut id="pointcut1" expression="execution(* com.imooc.aspectJ.demo2.CustomDaoImpl.save(..))"/> <!--配置aop的切面--> <aop:aspect ref="myAspectXml"> <!--配置前置增强--> <aop:before method="before" pointcut-ref="pointcut1"/> </aop:aspect> </aop:config> </beans>
这里要多配置一下aop的相关配置
1.aop:config
2.配置切入点
3.配置aop切面,配置增强方法
1.后置通知 + result
<!--xml中配置后置增强--> <aop:after-returning method="afterReturning" pointcut-ref="pointcut2" returning="result"/> //切面类中后置通知 public void afterReturning(Object result) { System.out.println("xml方式的后置通知" + result); }
2.环绕通知
- 在增强面的代码中
//环绕通知 public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("xml方式的环绕前通知"); Object obj = joinPoint.proceed();//执行目标方法 System.out.println("xml方式的环绕后通知"); return obj; }
- 在xml文件中
<!--配置切入点--> <aop:pointcut id="pointcut3" expression="execution(* com.imooc.aspectJ.demo2.CustomDaoImpl.delete())"/>
- 在切入面中
<!--配置环绕增强--> <aop:around method="around" pointcut-ref="pointcut3"/>
3.异常抛出通知
程序有异常时,执行
//异常抛出通知 public void afterThrowing(Throwable e) { System.out.println("xml方式的异常抛出通知" + e.getMessage()); }
//xml中==================
<aop:pointcut id="pointcut4" expression="execution(* com.imooc.aspectJ.demo2.CustomDaoImpl.findOne())"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="e"/>
```
4.最终通知
- 无论程序有无异常都会执行
标签:aop:after