前言: 
在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习.

一, AspectJ的概述:

AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。

Spring为了简化自身的AOP的开发,将AspectJ拿过来作为Spring自身一个AOP的开发.

二, Spring AspectJ开发实例

2.1 开发所需jar包

2.2 AspectJ 注解开发规范

2.2.1 @AspectJ提供不同的通知类型

@Before 前置通知,相当于BeforeAdvice
  在执行目标方法之前完成一个操作,获得到切入点信息.

@AfterReturning 后置通知,相当于AfterReturningAdvice

 在目标方法执行之后完成一个操作,获得方法的返回值.

 @AfterReturning(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.update(..))",returning="result")
public void afterReturing(Object result){
System.out.println("后置通知============"+result);
}

@Around 环绕通知,相当于MethodInterceptor

 在目标方法执行的前和执行后完成一个操作,阻止目标方法执行.

 @Around(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.delete(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前通知==========");
Object obj = joinPoint.proceed();
System.out.println("环绕后通知==========");
return obj;
}


@AfterThrowing抛出通知,相当于ThrowAdvice

 在目标方法出现异常的时候,完成一个操作.获得异常信息.

 @AfterThrowing(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))",throwing="e")
public void afterThrowing(Throwable e){
System.out.println("异常抛出通知========="+e.getMessage());
}

@After 最终final通知,不管是否异常,该通知都会执行

 在目标方法任何情况下都会执行的操作.相当于finally中的代码.

 @After(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))")
public void after(){
System.out.println("最终通知===========");
}


2.2.2 通过配置启用@AspectJ切面

 <?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">
<!-- 开启AspectJ自动代理-->
<aop:aspectj-autoproxy />
</beans>

2.2.3 在通知中通过value属性定义切点

通过execution函数,可以定义切点的方法切入
语法:
  execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
例如
  匹配所有类public方法 execution(public * *(..))
  匹配指定包下所有类方法 execution(* cn.itcast.dao.*(..)) 不包含子包
  execution(* cn.itcast.dao..*(..)) ..*表示包、子孙包下所有类
  匹配指定类所有方法 execution(* cn.itcast.service.UserService.*(..))
  匹配实现特定接口所有类方法 execution(* cn.itcast.dao.GenericDAO+.*(..))
  匹配所有save开头的方法 execution(* save*(..))

2.2.4 AspectJ的切入点:

 统一管理切入点的表达式.
@Pointcut(value="execution(* cn.itcast.aspectj.demo1.CustomerService+.find(..))")
private void myPointcut1(){} //这个类没有实际用途, 只是为了@Pointcut 注解


2.2.6 Aspect和Advisor的区别:

Advisor :传统的切面.传统切面一般都是由一个切入点和一个通知的组合.
Aspect :真正意义上的切面.由多个切入点和多个通知的组合.

2.3 Spring AspctJ 基于注解模式的开发
CustomerService.java:

 public interface CustomerService {

     public void save();
public Integer update();
public void delete();
public void find();
}

CustomerServiceImpl.java:

 public class CustomerServiceImpl implements CustomerService {

     @Override
public void save() {
System.out.println("保存客户...");
} @Override
public Integer update() {
System.out.println("修改客户...");
return 100;
} @Override
public void delete() {
System.out.println("删除客户...");
} @Override
public void find() {
System.out.println("查询客户...");
int d = 1 / 0;
} }

MyAspectAnno.java:

 /**
* 自定义切面类:
*
*/
@Aspect
public class MyAspectAnno { @Before(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.save(..))")
public void before(JoinPoint joinPoint){
System.out.println("前置通知============"+joinPoint);
} @AfterReturning(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.update(..))",returning="result")
public void afterReturing(Object result){
System.out.println("后置通知============"+result);
} @Around(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.delete(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前通知==========");
Object obj = joinPoint.proceed();
System.out.println("环绕后通知==========");
return obj;
} @AfterThrowing(value="MyAspectAnno.myPointcut1()",throwing="e")
public void afterThrowing(Throwable e){
System.out.println("异常抛出通知========="+e.getMessage());
} @After(value="MyAspectAnno.myPointcut1()")
public void after(){
System.out.println("最终通知===========");
} @Pointcut(value="execution(* cn.augmentum.aspectj.demo1.CustomerService+.find(..))")
private void myPointcut1(){}
}

SpringDemo.java 测试类:

 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 { @Resource(name = "customerService")
private CustomerService customerService; @Test
public void demo1() {
customerService.save();
customerService.update();
customerService.delete();
customerService.find();
}
}

applicationContext.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: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"> <!-- 使用注解完成AOP的开发 -->
<aop:aspectj-autoproxy/> <!-- 目标对象 -->
<bean id="customerService" class="cn.augmentum.aspectj.demo1.CustomerServiceImpl"/> <!-- 配置切面 -->
<bean id="myAspectAnno" class="cn.augmentum.aspectj.demo1.MyAspectAnno"/>
</beans>

2.4 Spring AspctJ 基于xml模式的开发

OrderService.java:

 public class OrderService {
public void save(){
System.out.println("保存订单...");
}
public Integer update(){
System.out.println("修改订单...");
return 200;
}
public void delete(){
System.out.println("删除订单...");
}
public void find(){
System.out.println("查询订单...");
//int d = 1/ 0;
}
}

MyAspectXml.java:

 public class MyAspectXml {

     public void before(){
System.out.println("前置通知===========");
} public void afterReturing(Object result){
System.out.println("后置通知==========="+result);
} public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕前通知==========");
Object obj = joinPoint.proceed();
System.out.println("环绕后通知==========");
return obj;
} public void afterThrowing(Throwable e){
System.out.println("异常抛出通知========"+e.getMessage());
} public void after(){
System.out.println("最终通知==========");
}
}

SpringDemo.java 测试类:

 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo2 { @Resource(name="orderService")
private OrderService orderService; @Test
public void demo1(){
orderService.save();
orderService.update();
orderService.delete();
orderService.find();
}
}

applicationContext.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: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 id="orderService" class="cn.augmentum.aspectj.demo2.OrderService"></bean> <!-- 配置切面 -->
<bean id="myAspectXml" class="cn.augmentum.aspectj.demo2.MyAspectXml"></bean> <!-- AOP的配置 -->
<aop:config>
<aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.save(..))" id="pointcut1"/>
<aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.update(..))" id="pointcut2"/>
<aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.delete(..))" id="pointcut3"/>
<aop:pointcut expression="execution(* cn.augmentum.aspectj.demo2.OrderService.find(..))" id="pointcut4"/>
<aop:aspect ref="myAspectXml">
<aop:before method="before" pointcut-ref="pointcut1"/>
<aop:after-returning method="afterReturing" pointcut-ref="pointcut2" returning="result"/>
<aop:around method="around" pointcut-ref="pointcut3"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="e"/>
<aop:after method="after" pointcut-ref="pointcut4"/>
</aop:aspect>
</aop:config>
</beans>

OK. 到了这里Spring 基于AOP的开发也总结完了, 学习之路漫漫, 谨以此记录成长的过程!

最新文章

  1. 智能头盔 &quot;Livall携全球首款智能骑行头盔亮相CES&quot;
  2. std::unique_lock&lt;std::mutex&gt; or std::lock_guard&lt;std::mutex&gt; C++11 区别
  3. 启动rabbitmq web管理后台插件
  4. CodeIgniter 3之Session类库(3)(转)
  5. show engine innodb status\G
  6. css开发经验&amp;错误习惯
  7. mysql之主从复制
  8. AngularCSS--关于angularjs动态加载css文件的方法(仅供参考)
  9. .Net语言 APP开发平台——Smobiler学习日志:如何在手机中调用邮件发送接口
  10. Kafka相关内容总结(Kafka集群搭建手记)
  11. JavaScript中的this所引用的对象和如何改变这个引用
  12. 访问arcserver中的featureServer服务
  13. MongoDB基础教程系列--目录结构
  14. 使用Eclipse Memory Analyzer 进行JAVA内存泄露分析
  15. 历届试题 买不到的数目-(dp)
  16. 外购半成品回写PR时将同一供应商同一编码的PR合并数量回写
  17. ns3 myfirst.cc 两个节点点对点通信
  18. MS datatype define(微软数据类型定义)
  19. mybatis plugin作为一款优秀的mybatis跳转插件
  20. Linux性能研究(总)

热门文章

  1. .net工具类
  2. October 26th Week 44th Wednesday 2016
  3. Java设计模式之工厂模式(Factory)
  4. DB2 中文排序问题
  5. MongoDB学习:(二)MongoDB简单使用
  6. simplexml_load_file 抑制警告的直接输出
  7. Docker 端口映射问题解决
  8. JS 学习笔记--2--变量的声明
  9. html页面布局 第8节
  10. windows多线程没那么难
  11. qt获取本机网络信息
  12. 剑指offer 22 栈的压入、弹出序列
  13. DeepLearning.ai学习笔记(四)卷积神经网络 -- week3 目标检测
  14. 【基础】26个命令玩转linux,菜鸟及面试必备
  15. Linux Vim查找字符串
  16. 【python小练】0001
  17. Python开发 基礎知識 2.變量 ( *arg, **kwargs )
  18. php中$this-&gt;是什么意思
  19. 如何使用mysql profiling功能分析单条查询语句
  20. Windows 8 应用程序前后台切换事件监听